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 System.Runtime.InteropServices;
using Allure.Net.Commons; using Allure.Net.Commons;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestResult = Allure.Net.Commons.TestResult; using TestResult = Allure.Net.Commons.TestResult;
namespace skyscraper8.Tests; namespace skyscraper8.Tests;
@ -28,7 +32,7 @@ public class Feyllure
writer.WriteLine($".NET={Environment.Version}"); writer.WriteLine($".NET={Environment.Version}");
writer.WriteLine($"Machine={Environment.MachineName}"); writer.WriteLine($"Machine={Environment.MachineName}");
writer.WriteLine($"User={Environment.UserName}"); 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}"); 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.AnnexC;
using skyscraper5.Docsis.MacManagement; using skyscraper5.Docsis.MacManagement;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace skyscraper8.Tests.ResourceTests namespace skyscraper8.Tests.ResourceTests
{ {

View File

@ -1,3 +1,6 @@
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
namespace skyscraper8.Tests.ResourceTests; 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;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory; using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
using skyscraper8.Skyscraper.Scraper.Storage; 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> // <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 // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// the code is regenerated. // der Code erneut generiert wird.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -11,32 +12,46 @@ namespace skyscraper8.Tests {
using System; using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] /// <summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()] /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()] /// </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 { 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() { internal Resources1() {
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] /// <summary>
internal static System.Resources.ResourceManager ResourceManager { /// 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 { get {
if (object.Equals(null, resourceMan)) { if (object.ReferenceEquals(resourceMan, null)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("skyscraper8.Tests.Resources1", typeof(Resources1).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("skyscraper8.Tests.Resources1", typeof(Resources1).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] /// <summary>
internal static System.Globalization.CultureInfo Culture { /// Ü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 { get {
return resourceCulture; return resourceCulture;
} }
@ -45,83 +60,9 @@ namespace skyscraper8.Tests {
} }
} }
internal static byte[] ModemCapabilitiesEncodingTest { /// <summary>
get { /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
object obj = ResourceManager.GetObject("ModemCapabilitiesEncodingTest", resourceCulture); /// </summary>
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));
}
}
internal static byte[] Frame00000008_TSGS1_MIS000_SYNC001 { internal static byte[] Frame00000008_TSGS1_MIS000_SYNC001 {
get { get {
object obj = ResourceManager.GetObject("Frame00000008_TSGS1_MIS000_SYNC001", resourceCulture); 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 { internal static byte[] Frame00000012_TSGS1_MIS000_SYNC001 {
get { get {
object obj = ResourceManager.GetObject("Frame00000012_TSGS1_MIS000_SYNC001", resourceCulture); object obj = ResourceManager.GetObject("Frame00000012_TSGS1_MIS000_SYNC001", resourceCulture);
return ((byte[])(obj)); 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,23 +1,123 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <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
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:element>
</xsd:schema> </xsd:schema>
<resheader name="resmimetype"> <resheader name="resmimetype">
<value>text/microsoft-resx</value> <value>text/microsoft-resx</value>
</resheader> </resheader>
<resheader name="version"> <resheader name="version">
<value>1.3</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </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"> <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> <value>Resources\ModemCapabilitiesEncodingTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
@ -57,4 +157,7 @@
<data name="Frame00000012_TSGS1_MIS000_SYNC001" type="System.Resources.ResXFileRef, System.Windows.Forms"> <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> <value>Resources\Frame00000012_TSGS1_MIS000_SYNC001.bbf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </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> </root>

View File

@ -1,4 +1,7 @@
using System;
using System.IO;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Docsis; using skyscraper5.Docsis;
using skyscraper5.Docsis.AnnexC; using skyscraper5.Docsis.AnnexC;
@ -20,7 +23,7 @@ public class DocsisTests : Feyllure
RcpIdEncoding rie = new RcpIdEncoding(new byte[] { 7, 1, 0 }); RcpIdEncoding rie = new RcpIdEncoding(new byte[] { 7, 1, 0 });
SimplifiedReceiveChannelAssignmentEncoding simplifiedReceiveChannelAssignmentEncoding = rie.SimplifiedReceiveChannelConfiguration; SimplifiedReceiveChannelAssignmentEncoding simplifiedReceiveChannelAssignmentEncoding = rie.SimplifiedReceiveChannelConfiguration;
Assert.IsNotNull(simplifiedReceiveChannelAssignmentEncoding); Assert.IsNotNull(simplifiedReceiveChannelAssignmentEncoding);
Assert.ThrowsException<NotImplementedException>(() => new RcpIdEncoding(new byte[] { 255, 1, 0 })); Assert.Throws<NotImplementedException>(() => new RcpIdEncoding(new byte[] { 255, 1, 0 }));
} }
[TestMethod] [TestMethod]
@ -30,7 +33,7 @@ public class DocsisTests : Feyllure
ushort epceEProt = epce.EProt; ushort epceEProt = epce.EProt;
Assert.AreEqual(1, epce.EProt); Assert.AreEqual(1, epce.EProt);
Assert.AreEqual(1, epce.Type); 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] [TestMethod]
@ -41,7 +44,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(0,srcae.DownstreamChannelAssignment[0]); Assert.AreEqual(0,srcae.DownstreamChannelAssignment[0]);
Assert.AreEqual(0, srcae.DownstreamProfileAssignment[0]); Assert.AreEqual(0, srcae.DownstreamProfileAssignment[0]);
Assert.AreEqual(0, srcae.PrimaryDownstreamChannelAssignment[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] [TestMethod]
@ -71,7 +74,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(0, tcco.P16Hi); Assert.AreEqual(0, tcco.P16Hi);
Assert.AreEqual(0, tcco.ListOfIucs[0]); Assert.AreEqual(0, tcco.ListOfIucs[0]);
Assert.ThrowsException<NotImplementedException>(() => Assert.Throws<NotImplementedException>(() =>
new CommonTlvEncodingObject.TransmitChannelConfigurationObject(new byte[] { 254, 1, 0 })); 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); Assert.AreEqual(new TimeSpan(0, 0, 1), commonTlv.InitializingChannelTimeout);
ms = new MemoryStream(new byte[] { 254, 1, 0 }); ms = new MemoryStream(new byte[] { 254, 1, 0 });
Assert.ThrowsException<NotImplementedException>(() => new CommonTlvEncodingObject(ms)); Assert.Throws<NotImplementedException>(() => new CommonTlvEncodingObject(ms));
} }
[TestMethod] [TestMethod]
@ -131,13 +134,13 @@ public class DocsisTests : Feyllure
Assert.AreEqual(GeneralPacketClassifierEncoding.DynamicServiceChangeActionEnum.Add, gpce.DynamicServiceChangeAction.Value); Assert.AreEqual(GeneralPacketClassifierEncoding.DynamicServiceChangeActionEnum.Add, gpce.DynamicServiceChangeAction.Value);
Assert.IsNotNull(gpce.EthernetLlcPacketClassificationEncodings); Assert.IsNotNull(gpce.EthernetLlcPacketClassificationEncodings);
Assert.ThrowsException<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[] Assert.Throws<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[]
{ {
12, 4, 12, 4,
255, 1, 0, 0 255, 1, 0, 0
})); }));
Assert.ThrowsException<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[] Assert.Throws<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[]
{ {
254, 1, 0 254, 1, 0
})); }));
@ -169,7 +172,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(1, ipce.SourcePortStart.Value); Assert.AreEqual(1, ipce.SourcePortStart.Value);
Assert.AreEqual(1, ipce.SourcePortEnd.Value); Assert.AreEqual(1, ipce.SourcePortEnd.Value);
Assert.ThrowsException<NotImplementedException>(() => Assert.Throws<NotImplementedException>(() =>
new GeneralPacketClassifierEncoding.Ipv4PacketClassificationEncodings(new byte[] new GeneralPacketClassifierEncoding.Ipv4PacketClassificationEncodings(new byte[]
{ {
255, 1, 0 255, 1, 0
@ -189,7 +192,7 @@ public class DocsisTests : Feyllure
Assert.IsNotNull(sfscao.SidClusterEncoding); Assert.IsNotNull(sfscao.SidClusterEncoding);
Assert.IsNotNull(sfscao.SidClusterSwitchoverCriteria); Assert.IsNotNull(sfscao.SidClusterSwitchoverCriteria);
Assert.ThrowsException<NotImplementedException>(() => new ServiceFlowSidClusterAssignmentObject(new byte[] Assert.Throws<NotImplementedException>(() => new ServiceFlowSidClusterAssignmentObject(new byte[]
{ {
255, 1, 0 255, 1, 0
})); }));
@ -207,7 +210,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(1, sceo.SidClusterId.Value); Assert.AreEqual(1, sceo.SidClusterId.Value);
Assert.IsNotNull(sceo.SidToChannelMapping); Assert.IsNotNull(sceo.SidToChannelMapping);
Assert.ThrowsException<NotImplementedException>(() => new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject(new byte[] Assert.Throws<NotImplementedException>(() => new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject(new byte[]
{ {
255, 1, 0 255, 1, 0
})); }));
@ -227,7 +230,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(1, stcmo.SID.Value); Assert.AreEqual(1, stcmo.SID.Value);
Assert.AreEqual(ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject.SidToChannelMappingObject.ActionEnum.Add,stcmo.Action.Value); Assert.AreEqual(ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject.SidToChannelMappingObject.ActionEnum.Add,stcmo.Action.Value);
Assert.ThrowsException<NotImplementedException>(() => Assert.Throws<NotImplementedException>(() =>
new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject.SidToChannelMappingObject(new byte[] new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject.SidToChannelMappingObject(new byte[]
{ {
255, 1, 0 255, 1, 0
@ -272,7 +275,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual((ushort)1, scsco.MaximumTimeInTheSidCluster); Assert.AreEqual((ushort)1, scsco.MaximumTimeInTheSidCluster);
buffer = new byte[] { 254, 1, 0 }; buffer = new byte[] { 254, 1, 0 };
Assert.ThrowsException<NotImplementedException>(() => Assert.Throws<NotImplementedException>(() =>
new ServiceFlowSidClusterAssignmentObject.SidClusterSwitchoverCriteriaObject(buffer)); new ServiceFlowSidClusterAssignmentObject.SidClusterSwitchoverCriteriaObject(buffer));
} }
@ -478,7 +481,7 @@ public class DocsisTests : Feyllure
{ {
255, 1, 1 255, 1, 1
}; };
Assert.ThrowsException<NotImplementedException>(() => new ModemCapabilitiesEncoding(buffer)); Assert.Throws<NotImplementedException>(() => new ModemCapabilitiesEncoding(buffer));
} }
[TestMethod] [TestMethod]
@ -555,7 +558,7 @@ public class DocsisTests : Feyllure
{ {
254, 1, 1 254, 1, 1
}; };
Assert.ThrowsException<NotImplementedException>(() => new GeneralServiceFlowEncoding(buffer)); Assert.Throws<NotImplementedException>(() => new GeneralServiceFlowEncoding(buffer));
} }
[MacManagementMessageType(0x90,0x01)] [MacManagementMessageType(0x90,0x01)]
@ -589,7 +592,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(srcAddr, tmmm.Source); Assert.AreEqual(srcAddr, tmmm.Source);
Assert.AreEqual(dstAddr, tmmm.Destination); 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); UntestableMacManagementMessage ummm = new UntestableMacManagementMessage(srcAddr, dstAddr, dataBuffer);
Assert.IsNull(ummm.MessageType); Assert.IsNull(ummm.MessageType);

View File

@ -1,3 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
namespace skyscraper8.Tests.RootTests; 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 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}" 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 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution 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}.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.ActiveCfg = Release|Any CPU
{1A29F6E6-4B6A-DCCD-1DF1-AA8D020E17D2}.Release|Any CPU.Build.0 = 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 {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{011164D8-B6FF-4BAB-B78D-0A174FC691E8}.Debug|Any CPU.Build.0 = Debug|Any CPU {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.Debug|Any CPU.Build.0 = Debug|Any CPU
{011164D8-B6FF-4BAB-B78D-0A174FC691E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.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}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE 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;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> &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/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; <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; &lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String> &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; <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; &lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String> &lt;/SessionState&gt;</s:String>

View File

@ -13,6 +13,7 @@ using System.Threading.Tasks;
using moe.yo3explorer.skyscraper8.DVBI.Model; using moe.yo3explorer.skyscraper8.DVBI.Model;
using skyscraper8.DvbI; using skyscraper8.DvbI;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using skyscraper8.Ietf.Rfc4566_SDP;
namespace skyscraper8.DvbNip namespace skyscraper8.DvbNip
{ {
@ -53,16 +54,28 @@ namespace skyscraper8.DvbNip
if (discoveryUdpPacket.DestinationPort == 3937) if (discoveryUdpPacket.DestinationPort == 3937)
{ {
LctFrame discoveryLctFrame = new LctFrame(discoveryUdpPacket.Payload); 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; CurrentCarrierInformation = discoveryLctFrame.LctHeader.NipActualCarrierInformation;
EventHandler.OnNipCarrierDetected(CurrentCarrierInformation); EventHandler.OnNipCarrierDetected(CurrentCarrierInformation);
bootstrapped = true; 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; return;
} }
UserDatagram udpPacket = new UserDatagram(ipv4Packet); UserDatagram udpPacket = new UserDatagram(ipv4Packet);
LctFrame lctFrame = new LctFrame(udpPacket.Payload); LctFrame lctFrame = new LctFrame(udpPacket.Payload);
if (lctFrame.LctHeader == null) if (lctFrame.LctHeader == null)
@ -114,6 +127,10 @@ namespace skyscraper8.DvbNip
SetFileAssociations(fluteListener, fdtAnnouncement); SetFileAssociations(fluteListener, fdtAnnouncement);
} }
} }
else
{
Console.WriteLine("aaa");
}
fluteStream.Close(); fluteStream.Close();
fluteStream.Dispose(); fluteStream.Dispose();
flutes.Remove(fluteCoordinate); flutes.Remove(fluteCoordinate);
@ -164,15 +181,43 @@ namespace skyscraper8.DvbNip
} }
} }
private DateTime? currentTime; private DateTime? currentTime;
private bool HandleMetadata(FluteListener fluteListener) private bool HandleMetadata(FluteListener fluteListener)
{ {
switch (fluteListener.FileAssociation.ContentLocation) switch (fluteListener.FileAssociation.ContentLocation)
{ {
case "urn:dvb:metadata:cs:NativeIPMulticastTransportObjectTypeCS:2023:bootstrap": case "urn:dvb:metadata:cs:NativeIPMulticastTransportObjectTypeCS:2023:bootstrap":
MulticastGatewayConfigurationType multicastGatewayConfiguration2023 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(fluteListener.ToStream()); Stream stream = fluteListener.ToStream();
if (DvbNipUtilities.IsXml(stream))
{
MulticastGatewayConfigurationType multicastGatewayConfiguration2023 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(stream);
EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2023); EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2023);
return true; 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:cs:MulticastTransportObjectTypeCS:2021:gateway-configuration": case "urn:dvb:metadata:cs:MulticastTransportObjectTypeCS:2021:gateway-configuration":
MulticastGatewayConfigurationType multicastGatewayConfiguration2021 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(fluteListener.ToStream()); MulticastGatewayConfigurationType multicastGatewayConfiguration2021 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(fluteListener.ToStream());
EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2021); EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2021);

View File

@ -1,9 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Serialization; using System.Xml.Serialization;
using MimeKit;
using skyscraper5.Skyscraper.IO;
using skyscraper8.Ietf.FLUTE; using skyscraper8.Ietf.FLUTE;
namespace skyscraper8.DvbNip namespace skyscraper8.DvbNip
@ -14,6 +17,57 @@ namespace skyscraper8.DvbNip
private static XmlSerializer multicastGatewayConfigurationXmlSerializer; 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) public static MulticastGatewayConfigurationType UnpackMulticastGatewayConfiguration(Stream stream)
{ {
if (multicastGatewayConfigurationXmlSerializer == null) if (multicastGatewayConfigurationXmlSerializer == null)
@ -120,6 +174,10 @@ namespace skyscraper8.DvbNip
{ {
bufferString = bufferString.Replace("urn:dvb:metadata:nativeip:2023", "urn:dvb:metadata:nativeip:2024"); 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)); object v = networkInformationFileXmlSerializer.Deserialize(new StringReader(bufferString));
NetworkInformationFileType result = (NetworkInformationFileType)v; NetworkInformationFileType result = (NetworkInformationFileType)v;
@ -141,10 +199,31 @@ namespace skyscraper8.DvbNip
{ {
bufferString = bufferString.Replace("urn:dvb:metadata:nativeip:2023", "urn:dvb:metadata:nativeip:2024"); 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)); object v = serviceInformationFileXmlSerializer.Deserialize(new StringReader(bufferString));
ServiceInformationFileType result = (ServiceInformationFileType)v; ServiceInformationFileType result = (ServiceInformationFileType)v;
return result; 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)); 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 NipNetworkId { get; }
public ushort NipCarrierId { get; } public ushort NipCarrierId { get; }
public ushort NipLinkId { get; } public ushort NipLinkId { get; }

View File

@ -47,7 +47,7 @@ public class Pts2Bbf2 : IBbframeDeencapsulator
if (!bbHeader.Valid) if (!bbHeader.Valid)
return; 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); string outfname = Path.Combine(outputDir.FullName, fname);
ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(bbframe, 11, bbframe.Length - 11); 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.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using MimeKit;
using skyscraper5.Teletext.Wss; using skyscraper5.Teletext.Wss;
namespace skyscraper8.Ietf.FLUTE namespace skyscraper8.Ietf.FLUTE
@ -148,7 +149,7 @@ namespace skyscraper8.Ietf.FLUTE
} }
} }
public Stream ToStream() public virtual Stream ToStream()
{ {
if (!IsComplete()) if (!IsComplete())
throw new InvalidOperationException(); throw new InvalidOperationException();

View File

@ -53,6 +53,11 @@ namespace skyscraper8.Ietf.FLUTE
return; return;
Payload = ms.ReadBytes(ms.GetAvailableBytes()); 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; } public int Version { get; }
@ -67,5 +72,19 @@ namespace skyscraper8.Ietf.FLUTE
public bool CloseObjectFlag { get; } public bool CloseObjectFlag { get; }
public FecHeader FecHeader { get; } public FecHeader FecHeader { get; }
public byte[] Payload { 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")) if (args[0].ToLowerInvariant().Equals("make-catalogue"))
{ {
DirectoryInfo di = new DirectoryInfo(args[1]); DirectoryInfo di = new DirectoryInfo(args[1]);
logger.InfoFormat("Input directory: {0}", di.FullName);
FileInfo fi = new FileInfo(args[2]); FileInfo fi = new FileInfo(args[2]);
logger.InfoFormat("Output File: {0}", fi.FullName);
CatalogueGenerator catalogueGenerator = new CatalogueGenerator(di, fi); CatalogueGenerator catalogueGenerator = new CatalogueGenerator(di, fi);
catalogueGenerator.Run(); catalogueGenerator.Run();
catalogueGenerator.Dispose(); catalogueGenerator.Dispose();

View File

@ -2,7 +2,7 @@
"profiles": { "profiles": {
"skyscraper8": { "skyscraper8": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "make-catalogue \"D:\\\\Stash\\\\\" \"D:\\\\index.csv\"", "commandLineArgs": "\"Z:\\Persönliches\\Satellitescommunity\\65W11304V.TS\"",
"remoteDebugEnabled": false "remoteDebugEnabled": false
}, },
"Container (Dockerfile)": { "Container (Dockerfile)": {

View File

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

View File

@ -333,5 +333,14 @@ namespace skyscraper5.Skyscraper.IO
stream.Position--; stream.Position--;
return readUInt8; 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.Reflection;
using System.Security.Policy; using System.Security.Policy;
using System.Text; using System.Text;
using MimeKit;
using skyscraper5.src.InteractionChannel.Model2; using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.Abertis; using skyscraper8.Abertis;
using skyscraper8.Experimentals.NdsSsu; using skyscraper8.Experimentals.NdsSsu;
@ -85,6 +86,7 @@ using skyscraper8.GS;
using skyscraper8.GSE; using skyscraper8.GSE;
using skyscraper8.GSE.GSE; using skyscraper8.GSE.GSE;
using skyscraper8.Ieee802_1AB; using skyscraper8.Ieee802_1AB;
using skyscraper8.Ietf;
using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2; using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors; using skyscraper8.InteractionChannel.Model2.Descriptors;
@ -2738,6 +2740,34 @@ namespace skyscraper5.Skyscraper.Scraper
public void FluteFileArrival(NipActualCarrierInformation carrier, FluteListener listener) public void FluteFileArrival(NipActualCarrierInformation carrier, FluteListener listener)
{ {
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(); string extension = Path.GetExtension(listener.FileAssociation.ContentLocation).ToLowerInvariant();
if (!DvbNipUtilities.IsContinuousFileType(extension)) if (!DvbNipUtilities.IsContinuousFileType(extension))
LogEvent(SkyscraperContextEvent.FluteFileArrival, listener.FileAssociation.ContentLocation); LogEvent(SkyscraperContextEvent.FluteFileArrival, listener.FileAssociation.ContentLocation);

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using log4net;
using skyscraper5.Skyscraper.Text.Encodings; using skyscraper5.Skyscraper.Text.Encodings;
namespace skyscraper5.Skyscraper.Text namespace skyscraper5.Skyscraper.Text
@ -36,18 +37,20 @@ namespace skyscraper5.Skyscraper.Text
} }
} }
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
private List<int> encodings;
public override Encoding? GetEncoding(int codepage) public override Encoding? GetEncoding(int codepage)
{ {
if (codepage == 1200) if (encodings == null)
return null; encodings = new List<int>();
if (codepage == 65001) if (!encodings.Contains(codepage))
return null; {
logger.InfoFormat("Detected text encoding: {0}", codepage);
encodings.Add(codepage);
}
if (codepage == 0)
return null; return null;
throw new NotImplementedException();
} }
public override Encoding? GetEncoding(string name) public override Encoding? GetEncoding(string name)

View File

@ -4,7 +4,7 @@ namespace skyscraper8;
public class VersionInfo public class VersionInfo
{ {
private const int PUBLIC_RELEASE = 13; private const int PUBLIC_RELEASE = 14;
public static int GetPublicReleaseNumber() public static int GetPublicReleaseNumber()
{ {

View File

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