From 4fcce3bc8703c2a48e1b0974865438d2227be509 Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Mon, 8 Sep 2025 22:58:22 +0200 Subject: [PATCH] Implemented a method to automatically find the IP Address of a SAT async = _minioClient.StatObjectAsync(statObjectArgs); + ObjectStat asyncResult = async.Result; + + ObjectRetriever objectRetriever = new ObjectRetriever(asyncResult.Size); + GetObjectArgs getObjectArgs = new GetObjectArgs(); + getObjectArgs.WithBucket(_minioBucket); + getObjectArgs = getObjectArgs.WithObject(fullName); + getObjectArgs.WithCallbackStream(objectRetriever.OurAction); + Task objectAsync = _minioClient.GetObjectAsync(getObjectArgs); + ObjectStat objectStat = objectAsync.Result; + return objectRetriever.GetBuffer(); + } + + public class ObjectRetriever + { + public ObjectRetriever(long size) + { + buffer = new byte[size]; + } + + private byte[] buffer; + public void OurAction(Stream obj) + { + int read = obj.Read(buffer, 0, (int)buffer.Length); + if (read != buffer.Length) + throw new MinioException("incomplete read"); + } + + public byte[] GetBuffer() + { + return buffer; + } + } + private void CleanTaskList() { while (true) @@ -415,5 +456,24 @@ namespace skyscraper5.Data string path = String.Format("/NDS-SSU/{0}/{1}/{2}/{3}", cnid, ctsid, pid.ToString(), fname); return FileExists(path); } + + public bool SsdpDeviceKnown(SsdpDevice ssdpDevice) + { + string filename = String.Format("/SSDP/{0}.xml", ssdpDevice.UniqueServiceName.SanitizeFileName()); + return FileExists(filename); + } + + public void SsdpStoreMetadata(SsdpDevice ssdpDevice, byte[] ssdpMetadataByteArray) + { + string filename = String.Format("/SSDP/{0}.xml", ssdpDevice.UniqueServiceName.SanitizeFileName()); + WriteObject(filename, new MemoryStream(ssdpMetadataByteArray)); + } + + public byte[] SsdpGetMetadata(SsdpDevice ssdpDevice) + { + string filename = String.Format("/SSDP/{0}.xml", ssdpDevice.UniqueServiceName.SanitizeFileName()); + byte[] bytes = GetObject(filename); + return bytes; + } } } diff --git a/Documentation/SSDP-XSD/device.cs b/Documentation/SSDP-XSD/device.cs new file mode 100644 index 0000000..acaadb3 --- /dev/null +++ b/Documentation/SSDP-XSD/device.cs @@ -0,0 +1,439 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +// +// This source code was auto-generated by xsd, Version=4.8.9037.0. +// +namespace skyscraper8.Ssdp.Schema { + using System.Xml.Serialization; + + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-upnp-org:device-1-0")] + [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:schemas-upnp-org:device-1-0", IsNullable=false)] + public partial class root { + + private SpecVersionType specVersionField; + + private string uRLBaseField; + + private DeviceType deviceField; + + private System.Xml.XmlAttribute[] anyAttrField; + + /// + public SpecVersionType specVersion { + get { + return this.specVersionField; + } + set { + this.specVersionField = value; + } + } + + /// + public string URLBase { + get { + return this.uRLBaseField; + } + set { + this.uRLBaseField = value; + } + } + + /// + public DeviceType device { + get { + return this.deviceField; + } + set { + this.deviceField = value; + } + } + + /// + [System.Xml.Serialization.XmlAnyAttributeAttribute()] + public System.Xml.XmlAttribute[] AnyAttr { + get { + return this.anyAttrField; + } + set { + this.anyAttrField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-upnp-org:device-1-0")] + public partial class SpecVersionType { + + private int majorField; + + private int minorField; + + /// + public int major { + get { + return this.majorField; + } + set { + this.majorField = value; + } + } + + /// + public int minor { + get { + return this.minorField; + } + set { + this.minorField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:schemas-upnp-org:device-1-0")] + public partial class DeviceType { + + private string deviceTypeField; + + private string friendlyNameField; + + private string manufacturerField; + + private string manufacturerURLField; + + private string modelDescriptionField; + + private string modelNameField; + + private string modelNumberField; + + private string modelURLField; + + private string serialNumberField; + + private string uDNField; + + private string uPCField; + + private IconListTypeIcon[] iconListField; + + private ServiceListTypeService[] serviceListField; + + private DeviceType[] deviceListField; + + private string presentationURLField; + + /// + public string deviceType { + get { + return this.deviceTypeField; + } + set { + this.deviceTypeField = value; + } + } + + /// + public string friendlyName { + get { + return this.friendlyNameField; + } + set { + this.friendlyNameField = value; + } + } + + /// + public string manufacturer { + get { + return this.manufacturerField; + } + set { + this.manufacturerField = value; + } + } + + /// + public string manufacturerURL { + get { + return this.manufacturerURLField; + } + set { + this.manufacturerURLField = value; + } + } + + /// + public string modelDescription { + get { + return this.modelDescriptionField; + } + set { + this.modelDescriptionField = value; + } + } + + /// + public string modelName { + get { + return this.modelNameField; + } + set { + this.modelNameField = value; + } + } + + /// + public string modelNumber { + get { + return this.modelNumberField; + } + set { + this.modelNumberField = value; + } + } + + /// + public string modelURL { + get { + return this.modelURLField; + } + set { + this.modelURLField = value; + } + } + + /// + public string serialNumber { + get { + return this.serialNumberField; + } + set { + this.serialNumberField = value; + } + } + + /// + public string UDN { + get { + return this.uDNField; + } + set { + this.uDNField = value; + } + } + + /// + public string UPC { + get { + return this.uPCField; + } + set { + this.uPCField = value; + } + } + + /// + [System.Xml.Serialization.XmlArrayItemAttribute("icon", IsNullable=false)] + public IconListTypeIcon[] iconList { + get { + return this.iconListField; + } + set { + this.iconListField = value; + } + } + + /// + [System.Xml.Serialization.XmlArrayItemAttribute("service", IsNullable=false)] + public ServiceListTypeService[] serviceList { + get { + return this.serviceListField; + } + set { + this.serviceListField = value; + } + } + + /// + [System.Xml.Serialization.XmlArrayItemAttribute("device", IsNullable=false)] + public DeviceType[] deviceList { + get { + return this.deviceListField; + } + set { + this.deviceListField = value; + } + } + + /// + public string presentationURL { + get { + return this.presentationURLField; + } + set { + this.presentationURLField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-upnp-org:device-1-0")] + public partial class IconListTypeIcon { + + private string mimetypeField; + + private int widthField; + + private int heightField; + + private int depthField; + + private string urlField; + + /// + public string mimetype { + get { + return this.mimetypeField; + } + set { + this.mimetypeField = value; + } + } + + /// + public int width { + get { + return this.widthField; + } + set { + this.widthField = value; + } + } + + /// + public int height { + get { + return this.heightField; + } + set { + this.heightField = value; + } + } + + /// + public int depth { + get { + return this.depthField; + } + set { + this.depthField = value; + } + } + + /// + public string url { + get { + return this.urlField; + } + set { + this.urlField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:schemas-upnp-org:device-1-0")] + public partial class ServiceListTypeService { + + private string serviceTypeField; + + private string serviceIdField; + + private string sCPDURLField; + + private string controlURLField; + + private string eventSubURLField; + + /// + public string serviceType { + get { + return this.serviceTypeField; + } + set { + this.serviceTypeField = value; + } + } + + /// + public string serviceId { + get { + return this.serviceIdField; + } + set { + this.serviceIdField = value; + } + } + + /// + public string SCPDURL { + get { + return this.sCPDURLField; + } + set { + this.sCPDURLField = value; + } + } + + /// + public string controlURL { + get { + return this.controlURLField; + } + set { + this.controlURLField = value; + } + } + + /// + public string eventSubURL { + get { + return this.eventSubURLField; + } + set { + this.eventSubURLField = value; + } + } + } +} diff --git a/Documentation/SSDP-XSD/device.xsd b/Documentation/SSDP-XSD/device.xsd new file mode 100644 index 0000000..e3b8b85 --- /dev/null +++ b/Documentation/SSDP-XSD/device.xsd @@ -0,0 +1,94 @@ + + + + + + XML Schema for UPnP device descriptions in real XSD format + (not like the XDR one from Microsoft) + Created by Michael Weinrich 2007 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Documentation/SSDP-XSD/make-classes.bat b/Documentation/SSDP-XSD/make-classes.bat new file mode 100644 index 0000000..3c41e55 --- /dev/null +++ b/Documentation/SSDP-XSD/make-classes.bat @@ -0,0 +1,3 @@ +"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8.1 Tools\x64\xsd.exe" /classes device.xsd /namespace:skyscraper8.Ssdp.Schema + +pause \ No newline at end of file diff --git a/skyscraper8/Ietf/FLUTE/FluteListener.cs b/skyscraper8/Ietf/FLUTE/FluteListener.cs index 93435cc..c7b2192 100644 --- a/skyscraper8/Ietf/FLUTE/FluteListener.cs +++ b/skyscraper8/Ietf/FLUTE/FluteListener.cs @@ -170,6 +170,7 @@ namespace skyscraper8.Ietf.FLUTE case "null": case "ll": case "nunull": + case "nulull": break; case "gzip": GZipStream level2 = new GZipStream(level1, CompressionMode.Decompress, false); diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index ce2a669..01ee76d 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -47,55 +47,64 @@ namespace skyscraper5 { Console.WriteLine("SSDP device: {0}", ssdpDevice.Server); }*/ - - /*RtspClient rtspClient = new RtspClient("172.20.20.121", 554); - rtspClient.AutoReconnect = true; - RtspOptionsResponse options = rtspClient.GetOptions("/"); - string url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); - RtspDescribeResponse describe = rtspClient.GetDescribe(url); - SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); - int rtcps = 0; - int rtps = 0; + //"urn:ses-com:device:SatIPServer:1" + PluginManager pluginManager = PluginManager.GetInstance(); + StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance(); + ObjectStorageFactory objectStorageFactory = storageConnectionManager.GetDefaultObjectStorageFactory(); + ObjectStorage objectStorage = objectStorageFactory.CreateObjectStorage(); - RtspSetupResponse setup = rtspClient.GetSetup(url); - setup.OnRtcpPacket += ((data, length) => - rtcps++); - setup.OnRtpPacket += (data, length) => - rtps++; + SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, objectStorage); + Console.WriteLine(firstSatIpServer.GetIpAddress()); - RtspPlayResponse play = rtspClient.GetPlay(setup); + /*RtspClient rtspClient = new RtspClient("172.20.20.121", 554); + rtspClient.AutoReconnect = true; + RtspOptionsResponse options = rtspClient.GetOptions("/"); + string url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); + RtspDescribeResponse describe = rtspClient.GetDescribe(url); + SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); - Thread.Sleep(5000); + int rtcps = 0; + int rtps = 0; - rtspClient.GetTeardown(setup); - Console.WriteLine("{0} RTCPs",rtcps); - Console.WriteLine("{0} RTPs",rtps); + RtspSetupResponse setup = rtspClient.GetSetup(url); + setup.OnRtcpPacket += ((data, length) => + rtcps++); + setup.OnRtpPacket += (data, length) => + rtps++; - Thread.Sleep(1000);*/ + RtspPlayResponse play = rtspClient.GetPlay(setup); - /*url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); - describe = rtspClient.GetDescribe(url); - sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); + Thread.Sleep(5000); - rtcps = 0; - rtps = 0; + rtspClient.GetTeardown(setup); + Console.WriteLine("{0} RTCPs",rtcps); + Console.WriteLine("{0} RTPs",rtps); - setup = rtspClient.GetSetup(url); - setup.OnRtcpPacket += ((data, length) => - rtcps++); - setup.OnRtpPacket += (data, length) => - rtps++; + Thread.Sleep(1000);*/ - play = rtspClient.GetPlay(setup); + /*url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); + describe = rtspClient.GetDescribe(url); + sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); - Thread.Sleep(5000); + rtcps = 0; + rtps = 0; - rtspClient.AutoReconnect = false; - rtspClient.GetTeardown(setup); - Console.WriteLine("{0} RTCPs", rtcps); - Console.WriteLine("{0} RTPs", rtps);*/ - //rtspClient.Dispose(); + setup = rtspClient.GetSetup(url); + setup.OnRtcpPacket += ((data, length) => + rtcps++); + setup.OnRtpPacket += (data, length) => + rtps++; + + play = rtspClient.GetPlay(setup); + + Thread.Sleep(5000); + + rtspClient.AutoReconnect = false; + rtspClient.GetTeardown(setup); + Console.WriteLine("{0} RTCPs", rtcps); + Console.WriteLine("{0} RTPs", rtps);*/ + //rtspClient.Dispose(); } static void Main(string[] args) diff --git a/skyscraper8/SatIp/IRtspCache.cs b/skyscraper8/SatIp/IRtspCache.cs new file mode 100644 index 0000000..9bc0bc3 --- /dev/null +++ b/skyscraper8/SatIp/IRtspCache.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper8.SimpleServiceDiscoveryProtocol; + +namespace skyscraper8.SatIp +{ + public interface IRtspCache + { + bool SsdpDeviceKnown(SsdpDevice ssdpDevice); + void SsdpStoreMetadata(SsdpDevice ssdpDevice, byte[] ssdpMetadataByteArray); + byte[] SsdpGetMetadata(SsdpDevice ssdpDevice); + } +} diff --git a/skyscraper8/SatIp/Schema/Schema.cs b/skyscraper8/SatIp/Schema/Schema.cs new file mode 100644 index 0000000..b202477 --- /dev/null +++ b/skyscraper8/SatIp/Schema/Schema.cs @@ -0,0 +1,538 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +// +// This source code was auto-generated by xsd, Version=4.8.9037.0. +// +namespace skyscraper8.Ssdp.Schema +{ + using System.Xml.Serialization; + + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:schemas-upnp-org:device-1-0")] + [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:schemas-upnp-org:device-1-0", IsNullable = false)] + public partial class root + { + + private SpecVersionType specVersionField; + + private string uRLBaseField; + + private DeviceType deviceField; + + private System.Xml.XmlAttribute[] anyAttrField; + + /// + public SpecVersionType specVersion + { + get + { + return this.specVersionField; + } + set + { + this.specVersionField = value; + } + } + + /// + public string URLBase + { + get + { + return this.uRLBaseField; + } + set + { + this.uRLBaseField = value; + } + } + + /// + public DeviceType device + { + get + { + return this.deviceField; + } + set + { + this.deviceField = value; + } + } + + /// + [System.Xml.Serialization.XmlAnyAttributeAttribute()] + public System.Xml.XmlAttribute[] AnyAttr + { + get + { + return this.anyAttrField; + } + set + { + this.anyAttrField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:schemas-upnp-org:device-1-0")] + public partial class SpecVersionType + { + + private int majorField; + + private int minorField; + + /// + public int major + { + get + { + return this.majorField; + } + set + { + this.majorField = value; + } + } + + /// + public int minor + { + get + { + return this.minorField; + } + set + { + this.minorField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:schemas-upnp-org:device-1-0")] + public partial class DeviceType + { + + private string deviceTypeField; + + private string friendlyNameField; + + private string manufacturerField; + + private string manufacturerURLField; + + private string modelDescriptionField; + + private string modelNameField; + + private string modelNumberField; + + private string modelURLField; + + private string serialNumberField; + + private string uDNField; + + private string uPCField; + + private IconListTypeIcon[] iconListField; + + private ServiceListTypeService[] serviceListField; + + private DeviceType[] deviceListField; + + private string presentationURLField; + + /// + public string deviceType + { + get + { + return this.deviceTypeField; + } + set + { + this.deviceTypeField = value; + } + } + + /// + public string friendlyName + { + get + { + return this.friendlyNameField; + } + set + { + this.friendlyNameField = value; + } + } + + /// + public string manufacturer + { + get + { + return this.manufacturerField; + } + set + { + this.manufacturerField = value; + } + } + + /// + public string manufacturerURL + { + get + { + return this.manufacturerURLField; + } + set + { + this.manufacturerURLField = value; + } + } + + /// + public string modelDescription + { + get + { + return this.modelDescriptionField; + } + set + { + this.modelDescriptionField = value; + } + } + + /// + public string modelName + { + get + { + return this.modelNameField; + } + set + { + this.modelNameField = value; + } + } + + /// + public string modelNumber + { + get + { + return this.modelNumberField; + } + set + { + this.modelNumberField = value; + } + } + + /// + public string modelURL + { + get + { + return this.modelURLField; + } + set + { + this.modelURLField = value; + } + } + + /// + public string serialNumber + { + get + { + return this.serialNumberField; + } + set + { + this.serialNumberField = value; + } + } + + /// + public string UDN + { + get + { + return this.uDNField; + } + set + { + this.uDNField = value; + } + } + + /// + public string UPC + { + get + { + return this.uPCField; + } + set + { + this.uPCField = value; + } + } + + /// + [System.Xml.Serialization.XmlArrayItemAttribute("icon", IsNullable = false)] + public IconListTypeIcon[] iconList + { + get + { + return this.iconListField; + } + set + { + this.iconListField = value; + } + } + + /// + [System.Xml.Serialization.XmlArrayItemAttribute("service", IsNullable = false)] + public ServiceListTypeService[] serviceList + { + get + { + return this.serviceListField; + } + set + { + this.serviceListField = value; + } + } + + /// + [System.Xml.Serialization.XmlArrayItemAttribute("device", IsNullable = false)] + public DeviceType[] deviceList + { + get + { + return this.deviceListField; + } + set + { + this.deviceListField = value; + } + } + + /// + public string presentationURL + { + get + { + return this.presentationURLField; + } + set + { + this.presentationURLField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:schemas-upnp-org:device-1-0")] + public partial class IconListTypeIcon + { + + private string mimetypeField; + + private int widthField; + + private int heightField; + + private int depthField; + + private string urlField; + + /// + public string mimetype + { + get + { + return this.mimetypeField; + } + set + { + this.mimetypeField = value; + } + } + + /// + public int width + { + get + { + return this.widthField; + } + set + { + this.widthField = value; + } + } + + /// + public int height + { + get + { + return this.heightField; + } + set + { + this.heightField = value; + } + } + + /// + public int depth + { + get + { + return this.depthField; + } + set + { + this.depthField = value; + } + } + + /// + public string url + { + get + { + return this.urlField; + } + set + { + this.urlField = value; + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:schemas-upnp-org:device-1-0")] + public partial class ServiceListTypeService + { + + private string serviceTypeField; + + private string serviceIdField; + + private string sCPDURLField; + + private string controlURLField; + + private string eventSubURLField; + + /// + public string serviceType + { + get + { + return this.serviceTypeField; + } + set + { + this.serviceTypeField = value; + } + } + + /// + public string serviceId + { + get + { + return this.serviceIdField; + } + set + { + this.serviceIdField = value; + } + } + + /// + public string SCPDURL + { + get + { + return this.sCPDURLField; + } + set + { + this.sCPDURLField = value; + } + } + + /// + public string controlURL + { + get + { + return this.controlURLField; + } + set + { + this.controlURLField = value; + } + } + + /// + public string eventSubURL + { + get + { + return this.eventSubURLField; + } + set + { + this.eventSubURLField = value; + } + } + } +} diff --git a/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpClient.cs b/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpClient.cs index 8933343..f9f0303 100644 --- a/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpClient.cs +++ b/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpClient.cs @@ -7,6 +7,9 @@ using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; +using System.Xml.Serialization; +using skyscraper8.SatIp; +using skyscraper8.Ssdp.Schema; namespace skyscraper8.SimpleServiceDiscoveryProtocol { @@ -121,5 +124,67 @@ namespace skyscraper8.SimpleServiceDiscoveryProtocol logger.WarnFormat("Don't know how to rate IP address", address.Address.ToString()); return Int32.MinValue; } + + public static List GetSsdpDevices(int timeout = 1000, string searchTarget = null, IRtspCache cache = null) + { + List inputList = GetSsdpDevices(timeout).ToList(); + List outputList = new List(); + WebClient webClient = new WebClient(); + foreach (SsdpDevice ssdpDevice in inputList) + { + if (!string.IsNullOrEmpty(searchTarget)) + { + if (!searchTarget.Equals(ssdpDevice.SearchTarget)) + { + continue; + } + } + + skyscraper8.Ssdp.Schema.root ssdpMetadata = null; + if (cache != null) + { + if (cache.SsdpDeviceKnown(ssdpDevice)) + { + byte[] ssdpMetadataByteArray = cache.SsdpGetMetadata(ssdpDevice); + ssdpMetadata = UnpackSsdpMetadata(ssdpMetadataByteArray); + } + } + + if (ssdpMetadata == null) + { + byte[] ssdpMetadataByteArray = webClient.DownloadData(ssdpDevice.Location); + cache?.SsdpStoreMetadata(ssdpDevice, ssdpMetadataByteArray); + ssdpMetadata = UnpackSsdpMetadata(ssdpMetadataByteArray); + } + + ssdpDevice.DeviceMetadata = ssdpMetadata; + if (ssdpMetadata != null) + { + logger.Debug(String.Format("{2} is a {0} {1}", ssdpMetadata.device.manufacturer, ssdpMetadata.device.modelName,ssdpDevice.Server)); + } + outputList.Add(ssdpDevice); + } + + return outputList; + } + + public static SsdpDevice GetFirstSatIpServer(int timeout = 1000, IRtspCache cache = null) + { + List ssdpDevices = GetSsdpDevices(1000, "urn:ses-com:device:SatIPServer:1", cache); + return ssdpDevices.First(); + } + + private static XmlSerializer xmlSerializer; + private static skyscraper8.Ssdp.Schema.root UnpackSsdpMetadata(byte[] xmlBuffer) + { + if (xmlSerializer == null) + xmlSerializer = new XmlSerializer(typeof(root)); + + MemoryStream ms = new MemoryStream(xmlBuffer); + object deserialize = xmlSerializer.Deserialize(ms); + ms.Dispose(); + return (skyscraper8.Ssdp.Schema.root)deserialize; + } + } } diff --git a/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpDevice.cs b/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpDevice.cs index 4358fff..212d78a 100644 --- a/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpDevice.cs +++ b/skyscraper8/SimpleServiceDiscoveryProtocol/SsdpDevice.cs @@ -6,10 +6,11 @@ using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; +using skyscraper8.Ssdp.Schema; namespace skyscraper8.SimpleServiceDiscoveryProtocol { - internal class SsdpDevice : Validatable + public class SsdpDevice : Validatable { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); @@ -85,6 +86,7 @@ namespace skyscraper8.SimpleServiceDiscoveryProtocol } } + logger.DebugFormat("Found UPnP Device: {0}", Server); Valid = true; } @@ -121,5 +123,13 @@ namespace skyscraper8.SimpleServiceDiscoveryProtocol public string CacheControl { get; private set; } public int HttpStatusCode { get; private set; } + public root DeviceMetadata { get; set; } + + public IPAddress GetIpAddress() + { + Uri uri = new Uri(Location); + string uriHost = uri.Host; + return IPAddress.Parse(uriHost); + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index e1872b5..cab001e 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -31,7 +31,7 @@ using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; namespace skyscraper8.Skyscraper.Scraper.Storage { - public interface DataStorage : IDbBlindscanJobStorage, IDnsDataSource, DvbIDataStorage + public interface DataStorage : IDbBlindscanJobStorage, IDnsDataSource, DvbIDataStorage { bool StoreTeletextPage(int networkId, int transportStreamId, ushort programNumber, TeletextMagazine magazine, DateTime timestamp); bool TestForNitNetwork(NitNetwork nitNetwork); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index 4d48f1f..eeb2947 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -38,6 +38,7 @@ using skyscraper8.DvbNip; using skyscraper8.Experimentals.NdsSsu; using skyscraper8.Ietf.FLUTE; using skyscraper8.Ses; +using skyscraper8.SimpleServiceDiscoveryProtocol; using skyscraper8.Skyscraper.Drawing; using skyscraper8.Skyscraper.Scraper.Storage; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; @@ -1822,5 +1823,20 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem FileInfo fi = new FileInfo(path); return fi.Exists; } - } + + public bool SsdpDeviceKnown(SsdpDevice ssdpDevice) + { + throw new NotImplementedException(); + } + + public void SsdpStoreMetadata(SsdpDevice ssdpDevice, byte[] ssdpMetadataByteArray) + { + throw new NotImplementedException(); + } + + public byte[] SsdpGetMetadata(SsdpDevice ssdpDevice) + { + throw new NotImplementedException(); + } + } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs index bab73eb..939af83 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs @@ -8,6 +8,7 @@ using skyscraper5.Dvb.Descriptors; using skyscraper8.DvbNip; using skyscraper8.Experimentals.NdsSsu; using skyscraper8.Ietf.FLUTE; +using skyscraper8.SimpleServiceDiscoveryProtocol; using skyscraper8.Skyscraper.Drawing; namespace skyscraper8.Skyscraper.Scraper.Storage @@ -123,5 +124,20 @@ namespace skyscraper8.Skyscraper.Scraper.Storage { return true; } + + public bool SsdpDeviceKnown(SsdpDevice ssdpDevice) + { + return false; + } + + public void SsdpStoreMetadata(SsdpDevice ssdpDevice, byte[] ssdpMetadataByteArray) + { + + } + + public byte[] SsdpGetMetadata(SsdpDevice ssdpDevice) + { + throw new NotImplementedException(); + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs index 43bdbcb..cedf99d 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/ObjectStorage.cs @@ -10,11 +10,12 @@ using skyscraper5.Teletext; using skyscraper8.DvbNip; using skyscraper8.Experimentals.NdsSsu; using skyscraper8.Ietf.FLUTE; +using skyscraper8.SatIp; using skyscraper8.Skyscraper.Drawing; namespace skyscraper8.Skyscraper.Scraper.Storage { - public interface ObjectStorage + public interface ObjectStorage : IRtspCache { bool ObjectCarouselFileArrival(VfsFile vfsFile, int transportStreamId, int networkId); void DataCarouselModuleArrival(int currentNetworkId, int currentTransportStreamId, int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion, Stream result); diff --git a/skyscraper8/Skyscraper/StringExtensions.cs b/skyscraper8/Skyscraper/StringExtensions.cs index 026bdf7..31b0752 100644 --- a/skyscraper8/Skyscraper/StringExtensions.cs +++ b/skyscraper8/Skyscraper/StringExtensions.cs @@ -1,6 +1,8 @@ -namespace skyscraper5.Skyscraper +using System.Runtime.ExceptionServices; + +namespace skyscraper5.Skyscraper { - static class StringExtensions + public static class StringExtensions { public static bool IsNaturalNumeric(this string str) { @@ -13,5 +15,27 @@ return true; } + + public static string SanitizeFileName(this string str) + { + char[] invalidPathChars = Path.GetInvalidPathChars(); + char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); + + char[] charArray = str.ToCharArray(); + for (int i = 0; i < charArray.Length; i++) + { + if (invalidPathChars.Contains(charArray[i])) + { + charArray[i] = '_'; + } + + if (invalidFileNameChars.Contains(charArray[i])) + { + charArray[i] = '_'; + } + } + + return new string(charArray); + } } }