aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Startup.Common
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Startup.Common')
-rw-r--r--MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs75
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs339
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs207
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs239
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs67
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs745
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs491
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs1934
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs1012
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs495
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs75
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs393
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs153
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs563
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs245
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs201
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs208
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs195
-rw-r--r--MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs346
-rw-r--r--MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs60
-rw-r--r--MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs59
-rw-r--r--MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs24
-rw-r--r--MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs20
-rw-r--r--MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs248
-rw-r--r--MediaBrowser.Server.Startup.Common/INativeApp.cs106
-rw-r--r--MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs56
-rw-r--r--MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs48
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs105
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs79
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs68
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs59
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs203
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs37
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs68
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs105
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs57
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs65
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs60
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs160
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs116
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs88
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs140
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs149
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs688
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs251
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs348
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs182
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs25
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs90
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini100
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini102
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini134
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini40
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini206
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini106
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini156
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini60
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini127
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini19
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini103
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini127
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini19
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini107
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini101
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini96
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini30
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini10
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini24
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini47
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini111
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini79
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini60
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini30
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini199
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini35
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini23
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini49
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini31
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini10
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini30
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini28
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini24
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini28
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini37
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini31
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini67
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini48
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini70
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini28
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini15
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini39
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini110
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini20
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini14
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini47
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini44
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini85
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini112
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini74
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini38
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini30
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini13
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini34
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini59
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini84
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini19
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini77
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini47
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini28
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini80
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini13
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini57
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini99
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini33
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini14
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini81
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini53
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini42
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini14
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini29
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini43
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini38
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini24
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini51
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini27
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini37
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini31
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini22
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini12
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini25
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini32
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini44
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini14
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini47
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini32
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini12
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini52
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini14
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini17
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini19
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini18
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini12
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini25
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini32
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini32
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini41
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini32
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini43
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini23
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini42
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini72
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini85
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini14
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini64
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini40
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini38
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini79
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini37
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini73
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini55
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini81
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini57
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini83
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini16
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini97
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini69
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini41
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini19
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini20
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini38
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini40
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini29
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini23
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini41
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini98
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini40
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini38
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini112
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini84
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini72
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini16
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini51
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini27
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini41
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini67
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini67
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini107
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini24
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini43
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini17
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini33
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini76
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini151
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini62
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini42
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini13
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini117
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini34
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini106
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini64
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini18
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini16
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini92
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini11
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini116
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini39
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini80
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini94
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini69
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini73
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini110
-rw-r--r--MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini10
-rw-r--r--MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs53
-rw-r--r--MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj305
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs62
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs9
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs44
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs130
-rw-r--r--MediaBrowser.Server.Startup.Common/NativeEnvironment.cs19
-rw-r--r--MediaBrowser.Server.Startup.Common/StartupOptions.cs28
-rw-r--r--MediaBrowser.Server.Startup.Common/SystemEvents.cs50
-rw-r--r--MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs39
-rw-r--r--MediaBrowser.Server.Startup.Common/app.config11
-rw-r--r--MediaBrowser.Server.Startup.Common/packages.config5
230 files changed, 20190 insertions, 1048 deletions
diff --git a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs
deleted file mode 100644
index 1a0e2d973..000000000
--- a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using MediaBrowser.Controller;
-using System;
-
-namespace MediaBrowser.Server.Startup.Common.Browser
-{
- /// <summary>
- /// Class BrowserLauncher
- /// </summary>
- public static class BrowserLauncher
- {
- /// <summary>
- /// Opens the dashboard page.
- /// </summary>
- /// <param name="page">The page.</param>
- /// <param name="appHost">The app host.</param>
- public static void OpenDashboardPage(string page, IServerApplicationHost appHost)
- {
- var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page;
-
- OpenUrl(appHost, url);
- }
-
- /// <summary>
- /// Opens the community.
- /// </summary>
- public static void OpenCommunity(IServerApplicationHost appHost)
- {
- OpenUrl(appHost, "http://emby.media/community");
- }
-
- public static void OpenEmbyPremiere(IServerApplicationHost appHost)
- {
- OpenDashboardPage("supporterkey.html", appHost);
- }
-
- /// <summary>
- /// Opens the web client.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- public static void OpenWebClient(IServerApplicationHost appHost)
- {
- OpenDashboardPage("index.html", appHost);
- }
-
- /// <summary>
- /// Opens the dashboard.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- public static void OpenDashboard(IServerApplicationHost appHost)
- {
- OpenDashboardPage("dashboard.html", appHost);
- }
-
- /// <summary>
- /// Opens the URL.
- /// </summary>
- /// <param name="url">The URL.</param>
- private static void OpenUrl(IServerApplicationHost appHost, string url)
- {
- try
- {
- appHost.LaunchUrl(url);
- }
- catch (NotImplementedException)
- {
-
- }
- catch (Exception ex)
- {
- Console.WriteLine("Error launching url: " + url);
- Console.WriteLine(ex.Message);
- }
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs
new file mode 100644
index 000000000..a25c27073
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1.cs
@@ -0,0 +1,339 @@
+//
+// ASN1.cs: Abstract Syntax Notation 1 - micro-parser and generator
+//
+// Authors:
+// Sebastien Pouliot <sebastien@ximian.com>
+// Jesper Pedersen <jep@itplus.dk>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// (C) 2004 IT+ A/S (http://www.itplus.dk)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security {
+
+ // References:
+ // a. ITU ASN.1 standards (free download)
+ // http://www.itu.int/ITU-T/studygroups/com17/languages/
+
+ public class ASN1 {
+
+ private byte m_nTag;
+ private byte[] m_aValue;
+ private ArrayList elist;
+
+ public ASN1 () : this (0x00, null) {}
+
+ public ASN1 (byte tag) : this (tag, null) {}
+
+ public ASN1 (byte tag, byte[] data)
+ {
+ m_nTag = tag;
+ m_aValue = data;
+ }
+
+ public ASN1 (byte[] data)
+ {
+ m_nTag = data [0];
+
+ int nLenLength = 0;
+ int nLength = data [1];
+
+ if (nLength > 0x80) {
+ // composed length
+ nLenLength = nLength - 0x80;
+ nLength = 0;
+ for (int i = 0; i < nLenLength; i++) {
+ nLength *= 256;
+ nLength += data [i + 2];
+ }
+ }
+ else if (nLength == 0x80) {
+ // undefined length encoding
+ throw new NotSupportedException ("Undefined length encoding.");
+ }
+
+ m_aValue = new byte [nLength];
+ Buffer.BlockCopy (data, (2 + nLenLength), m_aValue, 0, nLength);
+
+ if ((m_nTag & 0x20) == 0x20) {
+ int nStart = (2 + nLenLength);
+ Decode (data, ref nStart, data.Length);
+ }
+ }
+
+ public int Count {
+ get {
+ if (elist == null)
+ return 0;
+ return elist.Count;
+ }
+ }
+
+ public byte Tag {
+ get { return m_nTag; }
+ }
+
+ public int Length {
+ get {
+ if (m_aValue != null)
+ return m_aValue.Length;
+ else
+ return 0;
+ }
+ }
+
+ public byte[] Value {
+ get {
+ if (m_aValue == null)
+ GetBytes ();
+ return (byte[]) m_aValue.Clone ();
+ }
+ set {
+ if (value != null)
+ m_aValue = (byte[]) value.Clone ();
+ }
+ }
+
+ private bool CompareArray (byte[] array1, byte[] array2)
+ {
+ bool bResult = (array1.Length == array2.Length);
+ if (bResult) {
+ for (int i = 0; i < array1.Length; i++) {
+ if (array1[i] != array2[i])
+ return false;
+ }
+ }
+ return bResult;
+ }
+
+ public bool Equals (byte[] asn1)
+ {
+ return CompareArray (this.GetBytes (), asn1);
+ }
+
+ public bool CompareValue (byte[] value)
+ {
+ return CompareArray (m_aValue, value);
+ }
+
+ public ASN1 Add (ASN1 asn1)
+ {
+ if (asn1 != null) {
+ if (elist == null)
+ elist = new ArrayList ();
+ elist.Add (asn1);
+ }
+ return asn1;
+ }
+
+ public virtual byte[] GetBytes ()
+ {
+ byte[] val = null;
+
+ if (Count > 0) {
+ int esize = 0;
+ ArrayList al = new ArrayList ();
+ foreach (ASN1 a in elist) {
+ byte[] item = a.GetBytes ();
+ al.Add (item);
+ esize += item.Length;
+ }
+ val = new byte [esize];
+ int pos = 0;
+ for (int i=0; i < elist.Count; i++) {
+ byte[] item = (byte[]) al[i];
+ Buffer.BlockCopy (item, 0, val, pos, item.Length);
+ pos += item.Length;
+ }
+ } else if (m_aValue != null) {
+ val = m_aValue;
+ }
+
+ byte[] der;
+ int nLengthLen = 0;
+
+ if (val != null) {
+ int nLength = val.Length;
+ // special for length > 127
+ if (nLength > 127) {
+ if (nLength <= Byte.MaxValue) {
+ der = new byte [3 + nLength];
+ Buffer.BlockCopy (val, 0, der, 3, nLength);
+ nLengthLen = 0x81;
+ der[2] = (byte)(nLength);
+ }
+ else if (nLength <= UInt16.MaxValue) {
+ der = new byte [4 + nLength];
+ Buffer.BlockCopy (val, 0, der, 4, nLength);
+ nLengthLen = 0x82;
+ der[2] = (byte)(nLength >> 8);
+ der[3] = (byte)(nLength);
+ }
+ else if (nLength <= 0xFFFFFF) {
+ // 24 bits
+ der = new byte [5 + nLength];
+ Buffer.BlockCopy (val, 0, der, 5, nLength);
+ nLengthLen = 0x83;
+ der [2] = (byte)(nLength >> 16);
+ der [3] = (byte)(nLength >> 8);
+ der [4] = (byte)(nLength);
+ }
+ else {
+ // max (Length is an integer) 32 bits
+ der = new byte [6 + nLength];
+ Buffer.BlockCopy (val, 0, der, 6, nLength);
+ nLengthLen = 0x84;
+ der [2] = (byte)(nLength >> 24);
+ der [3] = (byte)(nLength >> 16);
+ der [4] = (byte)(nLength >> 8);
+ der [5] = (byte)(nLength);
+ }
+ }
+ else {
+ // basic case (no encoding)
+ der = new byte [2 + nLength];
+ Buffer.BlockCopy (val, 0, der, 2, nLength);
+ nLengthLen = nLength;
+ }
+ if (m_aValue == null)
+ m_aValue = val;
+ }
+ else
+ der = new byte[2];
+
+ der[0] = m_nTag;
+ der[1] = (byte)nLengthLen;
+
+ return der;
+ }
+
+ // Note: Recursive
+ protected void Decode (byte[] asn1, ref int anPos, int anLength)
+ {
+ byte nTag;
+ int nLength;
+ byte[] aValue;
+
+ // minimum is 2 bytes (tag + length of 0)
+ while (anPos < anLength - 1) {
+ DecodeTLV (asn1, ref anPos, out nTag, out nLength, out aValue);
+ // sometimes we get trailing 0
+ if (nTag == 0)
+ continue;
+
+ ASN1 elm = Add (new ASN1 (nTag, aValue));
+
+ if ((nTag & 0x20) == 0x20) {
+ int nConstructedPos = anPos;
+ elm.Decode (asn1, ref nConstructedPos, nConstructedPos + nLength);
+ }
+ anPos += nLength; // value length
+ }
+ }
+
+ // TLV : Tag - Length - Value
+ protected void DecodeTLV (byte[] asn1, ref int pos, out byte tag, out int length, out byte[] content)
+ {
+ tag = asn1 [pos++];
+ length = asn1 [pos++];
+
+ // special case where L contains the Length of the Length + 0x80
+ if ((length & 0x80) == 0x80) {
+ int nLengthLen = length & 0x7F;
+ length = 0;
+ for (int i = 0; i < nLengthLen; i++)
+ length = length * 256 + asn1 [pos++];
+ }
+
+ content = new byte [length];
+ Buffer.BlockCopy (asn1, pos, content, 0, length);
+ }
+
+ public ASN1 this [int index] {
+ get {
+ try {
+ if ((elist == null) || (index >= elist.Count))
+ return null;
+ return (ASN1) elist [index];
+ }
+ catch (ArgumentOutOfRangeException) {
+ return null;
+ }
+ }
+ }
+
+ public ASN1 Element (int index, byte anTag)
+ {
+ try {
+ if ((elist == null) || (index >= elist.Count))
+ return null;
+
+ ASN1 elm = (ASN1) elist [index];
+ if (elm.Tag == anTag)
+ return elm;
+ else
+ return null;
+ }
+ catch (ArgumentOutOfRangeException) {
+ return null;
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder hexLine = new StringBuilder ();
+
+ // Add tag
+ hexLine.AppendFormat ("Tag: {0} {1}", m_nTag.ToString ("X2"), Environment.NewLine);
+
+ // Add length
+ hexLine.AppendFormat ("Length: {0} {1}", Value.Length, Environment.NewLine);
+
+ // Add value
+ hexLine.Append ("Value: ");
+ hexLine.Append (Environment.NewLine);
+ for (int i = 0; i < Value.Length; i++) {
+ hexLine.AppendFormat ("{0} ", Value [i].ToString ("X2"));
+ if ((i+1) % 16 == 0)
+ hexLine.AppendFormat (Environment.NewLine);
+ }
+ return hexLine.ToString ();
+ }
+
+ public void SaveToFile (string filename)
+ {
+ if (filename == null)
+ throw new ArgumentNullException ("filename");
+
+ using (FileStream fs = File.Create (filename)) {
+ byte[] data = GetBytes ();
+ fs.Write (data, 0, data.Length);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs
new file mode 100644
index 000000000..8a2a487c8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/ASN1Convert.cs
@@ -0,0 +1,207 @@
+//
+// ASN1Convert.cs: Abstract Syntax Notation 1 convertion routines
+//
+// Authors:
+// Sebastien Pouliot <sebastien@ximian.com>
+// Jesper Pedersen <jep@itplus.dk>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// (C) 2004 IT+ A/S (http://www.itplus.dk)
+// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Globalization;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ // References:
+ // a. ITU ASN.1 standards (free download)
+ // http://www.itu.int/ITU-T/studygroups/com17/languages/
+
+ public static class ASN1Convert {
+ // RFC3280, section 4.2.1.5
+ // CAs conforming to this profile MUST always encode certificate
+ // validity dates through the year 2049 as UTCTime; certificate validity
+ // dates in 2050 or later MUST be encoded as GeneralizedTime.
+
+ // Under 1.x this API requires a Local datetime to be provided
+ // Under 2.0 it will also accept a Utc datetime
+ static public ASN1 FromDateTime (DateTime dt)
+ {
+ if (dt.Year < 2050) {
+ // UTCTIME
+ return new ASN1 (0x17, Encoding.ASCII.GetBytes (
+ dt.ToUniversalTime ().ToString ("yyMMddHHmmss",
+ CultureInfo.InvariantCulture) + "Z"));
+ }
+ else {
+ // GENERALIZEDTIME
+ return new ASN1 (0x18, Encoding.ASCII.GetBytes (
+ dt.ToUniversalTime ().ToString ("yyyyMMddHHmmss",
+ CultureInfo.InvariantCulture) + "Z"));
+ }
+ }
+
+ static public ASN1 FromInt32 (Int32 value)
+ {
+ byte[] integer = BitConverterLE.GetBytes (value);
+ Array.Reverse (integer);
+ int x = 0;
+ while ((x < integer.Length) && (integer [x] == 0x00))
+ x++;
+ ASN1 asn1 = new ASN1 (0x02);
+ switch (x) {
+ case 0:
+ asn1.Value = integer;
+ break;
+ case 4:
+ asn1.Value = new byte [1];
+ break;
+ default:
+ byte[] smallerInt = new byte [4 - x];
+ Buffer.BlockCopy (integer, x, smallerInt, 0, smallerInt.Length);
+ asn1.Value = smallerInt;
+ break;
+ }
+ return asn1;
+ }
+
+ static public ASN1 FromOid (string oid)
+ {
+ if (oid == null)
+ throw new ArgumentNullException ("oid");
+
+ return new ASN1 (CryptoConfig.EncodeOID (oid));
+ }
+
+ static public ASN1 FromUnsignedBigInteger (byte[] big)
+ {
+ if (big == null)
+ throw new ArgumentNullException ("big");
+
+ // check for numbers that could be interpreted as negative (first bit)
+ if (big [0] >= 0x80) {
+ // in thie cas we add a new, empty, byte (position 0) so we're
+ // sure this will always be interpreted an unsigned integer.
+ // However we can't feed it into RSAParameters or DSAParameters
+ int length = big.Length + 1;
+ byte[] uinteger = new byte [length];
+ Buffer.BlockCopy (big, 0, uinteger, 1, length - 1);
+ big = uinteger;
+ }
+ return new ASN1 (0x02, big);
+ }
+
+ static public int ToInt32 (ASN1 asn1)
+ {
+ if (asn1 == null)
+ throw new ArgumentNullException ("asn1");
+ if (asn1.Tag != 0x02)
+ throw new FormatException ("Only integer can be converted");
+
+ int x = 0;
+ for (int i=0; i < asn1.Value.Length; i++)
+ x = (x << 8) + asn1.Value [i];
+ return x;
+ }
+
+ // Convert a binary encoded OID to human readable string representation of
+ // an OID (IETF style). Based on DUMPASN1.C from Peter Gutmann.
+ static public string ToOid (ASN1 asn1)
+ {
+ if (asn1 == null)
+ throw new ArgumentNullException ("asn1");
+
+ byte[] aOID = asn1.Value;
+ StringBuilder sb = new StringBuilder ();
+ // Pick apart the OID
+ byte x = (byte) (aOID[0] / 40);
+ byte y = (byte) (aOID[0] % 40);
+ if (x > 2) {
+ // Handle special case for large y if x = 2
+ y += (byte) ((x - 2) * 40);
+ x = 2;
+ }
+ sb.Append (x.ToString (CultureInfo.InvariantCulture));
+ sb.Append (".");
+ sb.Append (y.ToString (CultureInfo.InvariantCulture));
+ ulong val = 0;
+ for (x = 1; x < aOID.Length; x++) {
+ val = ((val << 7) | ((byte) (aOID [x] & 0x7F)));
+ if ( !((aOID [x] & 0x80) == 0x80)) {
+ sb.Append (".");
+ sb.Append (val.ToString (CultureInfo.InvariantCulture));
+ val = 0;
+ }
+ }
+ return sb.ToString ();
+ }
+
+ static public DateTime ToDateTime (ASN1 time)
+ {
+ if (time == null)
+ throw new ArgumentNullException ("time");
+
+ string t = Encoding.ASCII.GetString (time.Value);
+ // to support both UTCTime and GeneralizedTime (and not so common format)
+ string mask = null;
+ int year;
+ switch (t.Length) {
+ case 11:
+ // illegal format, still it's supported for compatibility
+ mask = "yyMMddHHmmZ";
+ break;
+ case 13:
+ // RFC3280: 4.1.2.5.1 UTCTime
+ year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
+ // Where YY is greater than or equal to 50, the
+ // year SHALL be interpreted as 19YY; and
+ // Where YY is less than 50, the year SHALL be
+ // interpreted as 20YY.
+ if (year >= 50)
+ t = "19" + t;
+ else
+ t = "20" + t;
+ mask = "yyyyMMddHHmmssZ";
+ break;
+ case 15:
+ mask = "yyyyMMddHHmmssZ"; // GeneralizedTime
+ break;
+ case 17:
+ // another illegal format (990630000000+1000), again supported for compatibility
+ year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
+ string century = (year >= 50) ? "19" : "20";
+ // ASN.1 (see ITU X.680 section 43.3) deals with offset differently than .NET
+ char sign = (t[12] == '+') ? '-' : '+';
+ t = String.Format ("{0}{1}{2}{3}{4}:{5}{6}", century, t.Substring (0, 12), sign,
+ t[13], t[14], t[15], t[16]);
+ mask = "yyyyMMddHHmmsszzz";
+ break;
+ }
+ return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs b/MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs
new file mode 100644
index 000000000..240c958a3
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/BitConverterLE.cs
@@ -0,0 +1,239 @@
+//
+// Mono.Security.BitConverterLE.cs
+// Like System.BitConverter but always little endian
+//
+// Author:
+// Bernie Solomon
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Emby.Common.Implementations.Security
+{
+ internal sealed class BitConverterLE
+ {
+ private BitConverterLE ()
+ {
+ }
+
+ unsafe private static byte[] GetUShortBytes (byte *bytes)
+ {
+ if (BitConverter.IsLittleEndian)
+ return new byte [] { bytes [0], bytes [1] };
+ else
+ return new byte [] { bytes [1], bytes [0] };
+ }
+
+ unsafe private static byte[] GetUIntBytes (byte *bytes)
+ {
+ if (BitConverter.IsLittleEndian)
+ return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3] };
+ else
+ return new byte [] { bytes [3], bytes [2], bytes [1], bytes [0] };
+ }
+
+ unsafe private static byte[] GetULongBytes (byte *bytes)
+ {
+ if (BitConverter.IsLittleEndian)
+ return new byte [] { bytes [0], bytes [1], bytes [2], bytes [3],
+ bytes [4], bytes [5], bytes [6], bytes [7] };
+ else
+ return new byte [] { bytes [7], bytes [6], bytes [5], bytes [4],
+ bytes [3], bytes [2], bytes [1], bytes [0] };
+ }
+
+ unsafe internal static byte[] GetBytes (bool value)
+ {
+ return new byte [] { value ? (byte)1 : (byte)0 };
+ }
+
+ unsafe internal static byte[] GetBytes (char value)
+ {
+ return GetUShortBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (short value)
+ {
+ return GetUShortBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (int value)
+ {
+ return GetUIntBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (long value)
+ {
+ return GetULongBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (ushort value)
+ {
+ return GetUShortBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (uint value)
+ {
+ return GetUIntBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (ulong value)
+ {
+ return GetULongBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (float value)
+ {
+ return GetUIntBytes ((byte *) &value);
+ }
+
+ unsafe internal static byte[] GetBytes (double value)
+ {
+ return GetULongBytes ((byte *) &value);
+ }
+
+ unsafe private static void UShortFromBytes (byte *dst, byte[] src, int startIndex)
+ {
+ if (BitConverter.IsLittleEndian) {
+ dst [0] = src [startIndex];
+ dst [1] = src [startIndex + 1];
+ } else {
+ dst [0] = src [startIndex + 1];
+ dst [1] = src [startIndex];
+ }
+ }
+
+ unsafe private static void UIntFromBytes (byte *dst, byte[] src, int startIndex)
+ {
+ if (BitConverter.IsLittleEndian) {
+ dst [0] = src [startIndex];
+ dst [1] = src [startIndex + 1];
+ dst [2] = src [startIndex + 2];
+ dst [3] = src [startIndex + 3];
+ } else {
+ dst [0] = src [startIndex + 3];
+ dst [1] = src [startIndex + 2];
+ dst [2] = src [startIndex + 1];
+ dst [3] = src [startIndex];
+ }
+ }
+
+ unsafe private static void ULongFromBytes (byte *dst, byte[] src, int startIndex)
+ {
+ if (BitConverter.IsLittleEndian) {
+ for (int i = 0; i < 8; ++i)
+ dst [i] = src [startIndex + i];
+ } else {
+ for (int i = 0; i < 8; ++i)
+ dst [i] = src [startIndex + (7 - i)];
+ }
+ }
+
+ unsafe internal static bool ToBoolean (byte[] value, int startIndex)
+ {
+ return value [startIndex] != 0;
+ }
+
+ unsafe internal static char ToChar (byte[] value, int startIndex)
+ {
+ char ret;
+
+ UShortFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static short ToInt16 (byte[] value, int startIndex)
+ {
+ short ret;
+
+ UShortFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static int ToInt32 (byte[] value, int startIndex)
+ {
+ int ret;
+
+ UIntFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static long ToInt64 (byte[] value, int startIndex)
+ {
+ long ret;
+
+ ULongFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static ushort ToUInt16 (byte[] value, int startIndex)
+ {
+ ushort ret;
+
+ UShortFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static uint ToUInt32 (byte[] value, int startIndex)
+ {
+ uint ret;
+
+ UIntFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static ulong ToUInt64 (byte[] value, int startIndex)
+ {
+ ulong ret;
+
+ ULongFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static float ToSingle (byte[] value, int startIndex)
+ {
+ float ret;
+
+ UIntFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+
+ unsafe internal static double ToDouble (byte[] value, int startIndex)
+ {
+ double ret;
+
+ ULongFromBytes ((byte *) &ret, value, startIndex);
+
+ return ret;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs b/MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs
new file mode 100644
index 000000000..9e14b7713
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/CertificateGenerator.cs
@@ -0,0 +1,67 @@
+using MediaBrowser.Model.Logging;
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+ public class CertificateGenerator
+ {
+ private const string MonoTestRootAgency = "<RSAKeyValue><Modulus>v/4nALBxCE+9JgEC0LnDUvKh6e96PwTpN4Rj+vWnqKT7IAp1iK/JjuqvAg6DQ2vTfv0dTlqffmHH51OyioprcT5nzxcSTsZb/9jcHScG0s3/FRIWnXeLk/fgm7mSYhjUaHNI0m1/NTTktipicjKxo71hGIg9qucCWnDum+Krh/k=</Modulus><Exponent>AQAB</Exponent><P>9jbKxMXEruW2CfZrzhxtull4O8P47+mNsEL+9gf9QsRO1jJ77C+jmzfU6zbzjf8+ViK+q62tCMdC1ZzulwdpXQ==</P><Q>x5+p198l1PkK0Ga2mRh0SIYSykENpY2aLXoyZD/iUpKYAvATm0/wvKNrE4dKJyPCA+y3hfTdgVag+SP9avvDTQ==</Q><DP>ISSjCvXsUfbOGG05eddN1gXxL2pj+jegQRfjpk7RAsnWKvNExzhqd5x+ZuNQyc6QH5wxun54inP4RTUI0P/IaQ==</DP><DQ>R815VQmR3RIbPqzDXzv5j6CSH6fYlcTiQRtkBsUnzhWmkd/y3XmamO+a8zJFjOCCx9CcjpVuGziivBqi65lVPQ==</DQ><InverseQ>iYiu0KwMWI/dyqN3RJYUzuuLj02/oTD1pYpwo2rvNCXU1Q5VscOeu2DpNg1gWqI+1RrRCsEoaTNzXB1xtKNlSw==</InverseQ><D>nIfh1LYF8fjRBgMdAH/zt9UKHWiaCnc+jXzq5tkR8HVSKTVdzitD8bl1JgAfFQD8VjSXiCJqluexy/B5SGrCXQ49c78NIQj0hD+J13Y8/E0fUbW1QYbhj6Ff7oHyhaYe1WOQfkp2t/h+llHOdt1HRf7bt7dUknYp7m8bQKGxoYE=</D></RSAKeyValue>";
+
+ public static void CreateSelfSignCertificatePfx(
+ string fileName,
+ string hostname,
+ ILogger logger)
+ {
+ if (string.IsNullOrWhiteSpace(fileName))
+ {
+ throw new ArgumentNullException("fileName");
+ }
+
+ byte[] sn = Guid.NewGuid().ToByteArray();
+ string subject = string.Format("CN={0}", hostname);
+ string issuer = subject;
+ DateTime notBefore = DateTime.Now.AddDays(-2);
+ DateTime notAfter = DateTime.Now.AddYears(10);
+
+ RSA issuerKey = RSA.Create();
+ issuerKey.FromXmlString(MonoTestRootAgency);
+ RSA subjectKey = RSA.Create();
+
+ // serial number MUST be positive
+ if ((sn[0] & 0x80) == 0x80)
+ sn[0] -= 0x80;
+
+ issuer = subject;
+ issuerKey = subjectKey;
+
+ X509CertificateBuilder cb = new X509CertificateBuilder(3);
+ cb.SerialNumber = sn;
+ cb.IssuerName = issuer;
+ cb.NotBefore = notBefore;
+ cb.NotAfter = notAfter;
+ cb.SubjectName = subject;
+ cb.SubjectPublicKey = subjectKey;
+
+ // signature
+ cb.Hash = "SHA256";
+ byte[] rawcert = cb.Sign(issuerKey);
+
+ PKCS12 p12 = new PKCS12();
+
+
+ ArrayList list = new ArrayList();
+ // we use a fixed array to avoid endianess issues
+ // (in case some tools requires the ID to be 1).
+ list.Add(new byte[4] { 1, 0, 0, 0 });
+ Hashtable attributes = new Hashtable(1);
+ attributes.Add(PKCS9.localKeyId, list);
+
+ p12.AddCertificate(new X509Certificate(rawcert), attributes);
+
+ p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
+ p12.SaveToFile(fileName);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs b/MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs
new file mode 100644
index 000000000..c6e466534
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/CryptoConvert.cs
@@ -0,0 +1,745 @@
+//
+// CryptoConvert.cs - Crypto Convertion Routines
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Globalization;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ public sealed class CryptoConvert {
+
+ private CryptoConvert ()
+ {
+ }
+
+ static private int ToInt32LE (byte [] bytes, int offset)
+ {
+ return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset];
+ }
+
+ static private uint ToUInt32LE (byte [] bytes, int offset)
+ {
+ return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]);
+ }
+
+ static private byte [] GetBytesLE (int val)
+ {
+ return new byte [] {
+ (byte) (val & 0xff),
+ (byte) ((val >> 8) & 0xff),
+ (byte) ((val >> 16) & 0xff),
+ (byte) ((val >> 24) & 0xff)
+ };
+ }
+
+ static private byte[] Trim (byte[] array)
+ {
+ for (int i=0; i < array.Length; i++) {
+ if (array [i] != 0x00) {
+ byte[] result = new byte [array.Length - i];
+ Buffer.BlockCopy (array, i, result, 0, result.Length);
+ return result;
+ }
+ }
+ return null;
+ }
+
+ // convert the key from PRIVATEKEYBLOB to RSA
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp
+ // e.g. SNK files, PVK files
+ static public RSA FromCapiPrivateKeyBlob (byte[] blob)
+ {
+ return FromCapiPrivateKeyBlob (blob, 0);
+ }
+
+ static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset)
+ {
+ if (blob == null)
+ throw new ArgumentNullException ("blob");
+ if (offset >= blob.Length)
+ throw new ArgumentException ("blob is too small.");
+
+ RSAParameters rsap = new RSAParameters ();
+ try {
+ if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07)
+ (blob [offset+1] != 0x02) || // Version (0x02)
+ (blob [offset+2] != 0x00) || // Reserved (word)
+ (blob [offset+3] != 0x00) ||
+ (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2
+ throw new CryptographicException ("Invalid blob header");
+
+ // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
+ // int algId = ToInt32LE (blob, offset+4);
+
+ // DWORD bitlen
+ int bitLen = ToInt32LE (blob, offset+12);
+
+ // DWORD public exponent
+ byte[] exp = new byte [4];
+ Buffer.BlockCopy (blob, offset+16, exp, 0, 4);
+ Array.Reverse (exp);
+ rsap.Exponent = Trim (exp);
+
+ int pos = offset+20;
+ // BYTE modulus[rsapubkey.bitlen/8];
+ int byteLen = (bitLen >> 3);
+ rsap.Modulus = new byte [byteLen];
+ Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
+ Array.Reverse (rsap.Modulus);
+ pos += byteLen;
+
+ // BYTE prime1[rsapubkey.bitlen/16];
+ int byteHalfLen = (byteLen >> 1);
+ rsap.P = new byte [byteHalfLen];
+ Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen);
+ Array.Reverse (rsap.P);
+ pos += byteHalfLen;
+
+ // BYTE prime2[rsapubkey.bitlen/16];
+ rsap.Q = new byte [byteHalfLen];
+ Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen);
+ Array.Reverse (rsap.Q);
+ pos += byteHalfLen;
+
+ // BYTE exponent1[rsapubkey.bitlen/16];
+ rsap.DP = new byte [byteHalfLen];
+ Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen);
+ Array.Reverse (rsap.DP);
+ pos += byteHalfLen;
+
+ // BYTE exponent2[rsapubkey.bitlen/16];
+ rsap.DQ = new byte [byteHalfLen];
+ Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen);
+ Array.Reverse (rsap.DQ);
+ pos += byteHalfLen;
+
+ // BYTE coefficient[rsapubkey.bitlen/16];
+ rsap.InverseQ = new byte [byteHalfLen];
+ Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
+ Array.Reverse (rsap.InverseQ);
+ pos += byteHalfLen;
+
+ // ok, this is hackish but CryptoAPI support it so...
+ // note: only works because CRT is used by default
+ // http://bugzilla.ximian.com/show_bug.cgi?id=57941
+ rsap.D = new byte [byteLen]; // must be allocated
+ if (pos + byteLen + offset <= blob.Length) {
+ // BYTE privateExponent[rsapubkey.bitlen/8];
+ Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen);
+ Array.Reverse (rsap.D);
+ }
+ }
+ catch (Exception e) {
+ throw new CryptographicException ("Invalid blob.", e);
+ }
+
+ RSA rsa = null;
+ try
+ {
+ rsa = RSA.Create();
+ rsa.ImportParameters(rsap);
+ }
+ catch (CryptographicException ce)
+ {
+ // this may cause problem when this code is run under
+ // the SYSTEM identity on Windows (e.g. ASP.NET). See
+ // http://bugzilla.ximian.com/show_bug.cgi?id=77559
+ try
+ {
+ CspParameters csp = new CspParameters();
+ csp.Flags = CspProviderFlags.UseMachineKeyStore;
+ rsa = new RSACryptoServiceProvider(csp);
+ rsa.ImportParameters(rsap);
+ }
+ catch
+ {
+ // rethrow original, not the later, exception if this fails
+ throw ce;
+ }
+ }
+ return rsa;
+ }
+
+ static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob)
+ {
+ return FromCapiPrivateKeyBlobDSA (blob, 0);
+ }
+
+ static public DSA FromCapiPrivateKeyBlobDSA (byte[] blob, int offset)
+ {
+ if (blob == null)
+ throw new ArgumentNullException ("blob");
+ if (offset >= blob.Length)
+ throw new ArgumentException ("blob is too small.");
+
+ DSAParameters dsap = new DSAParameters ();
+ try {
+ if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07)
+ (blob [offset + 1] != 0x02) || // Version (0x02)
+ (blob [offset + 2] != 0x00) || // Reserved (word)
+ (blob [offset + 3] != 0x00) ||
+ (ToUInt32LE (blob, offset + 8) != 0x32535344)) // DWORD magic
+ throw new CryptographicException ("Invalid blob header");
+
+ int bitlen = ToInt32LE (blob, offset + 12);
+ int bytelen = bitlen >> 3;
+ int pos = offset + 16;
+
+ dsap.P = new byte [bytelen];
+ Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen);
+ Array.Reverse (dsap.P);
+ pos += bytelen;
+
+ dsap.Q = new byte [20];
+ Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20);
+ Array.Reverse (dsap.Q);
+ pos += 20;
+
+ dsap.G = new byte [bytelen];
+ Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen);
+ Array.Reverse (dsap.G);
+ pos += bytelen;
+
+ dsap.X = new byte [20];
+ Buffer.BlockCopy (blob, pos, dsap.X, 0, 20);
+ Array.Reverse (dsap.X);
+ pos += 20;
+
+ dsap.Counter = ToInt32LE (blob, pos);
+ pos += 4;
+
+ dsap.Seed = new byte [20];
+ Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20);
+ Array.Reverse (dsap.Seed);
+ pos += 20;
+ }
+ catch (Exception e) {
+ throw new CryptographicException ("Invalid blob.", e);
+ }
+
+ DSA dsa = null;
+ try
+ {
+ dsa = (DSA)DSA.Create();
+ dsa.ImportParameters(dsap);
+ }
+ catch (CryptographicException ce)
+ {
+ // this may cause problem when this code is run under
+ // the SYSTEM identity on Windows (e.g. ASP.NET). See
+ // http://bugzilla.ximian.com/show_bug.cgi?id=77559
+ try
+ {
+ CspParameters csp = new CspParameters();
+ csp.Flags = CspProviderFlags.UseMachineKeyStore;
+ dsa = new DSACryptoServiceProvider(csp);
+ dsa.ImportParameters(dsap);
+ }
+ catch
+ {
+ // rethrow original, not the later, exception if this fails
+ throw ce;
+ }
+ }
+ return dsa;
+ }
+
+ static public byte[] ToCapiPrivateKeyBlob (RSA rsa)
+ {
+ RSAParameters p = rsa.ExportParameters (true);
+ int keyLength = p.Modulus.Length; // in bytes
+ byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)];
+
+ blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07)
+ blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
+ // [2], [3] // RESERVED - Always 0
+ blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
+ blob [8] = 0x52; // Magic - RSA2 (ASCII in hex)
+ blob [9] = 0x53;
+ blob [10] = 0x41;
+ blob [11] = 0x32;
+
+ byte[] bitlen = GetBytesLE (keyLength << 3);
+ blob [12] = bitlen [0]; // bitlen
+ blob [13] = bitlen [1];
+ blob [14] = bitlen [2];
+ blob [15] = bitlen [3];
+
+ // public exponent (DWORD)
+ int pos = 16;
+ int n = p.Exponent.Length;
+ while (n > 0)
+ blob [pos++] = p.Exponent [--n];
+ // modulus
+ pos = 20;
+ byte[] part = p.Modulus;
+ int len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+ // private key
+ part = p.P;
+ len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+
+ part = p.Q;
+ len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+
+ part = p.DP;
+ len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+
+ part = p.DQ;
+ len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+
+ part = p.InverseQ;
+ len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+
+ part = p.D;
+ len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+
+ return blob;
+ }
+
+ static public byte[] ToCapiPrivateKeyBlob (DSA dsa)
+ {
+ DSAParameters p = dsa.ExportParameters (true);
+ int keyLength = p.P.Length; // in bytes
+
+ // header + P + Q + G + X + count + seed
+ byte[] blob = new byte [16 + keyLength + 20 + keyLength + 20 + 4 + 20];
+
+ blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07)
+ blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
+ // [2], [3] // RESERVED - Always 0
+ blob [5] = 0x22; // ALGID
+ blob [8] = 0x44; // Magic
+ blob [9] = 0x53;
+ blob [10] = 0x53;
+ blob [11] = 0x32;
+
+ byte[] bitlen = GetBytesLE (keyLength << 3);
+ blob [12] = bitlen [0];
+ blob [13] = bitlen [1];
+ blob [14] = bitlen [2];
+ blob [15] = bitlen [3];
+
+ int pos = 16;
+ byte[] part = p.P;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, keyLength);
+ pos += keyLength;
+
+ part = p.Q;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, 20);
+ pos += 20;
+
+ part = p.G;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, keyLength);
+ pos += keyLength;
+
+ part = p.X;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, 20);
+ pos += 20;
+
+ Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4);
+ pos += 4;
+
+ part = p.Seed;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, 20);
+
+ return blob;
+ }
+
+ static public RSA FromCapiPublicKeyBlob (byte[] blob)
+ {
+ return FromCapiPublicKeyBlob (blob, 0);
+ }
+
+ static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset)
+ {
+ if (blob == null)
+ throw new ArgumentNullException ("blob");
+ if (offset >= blob.Length)
+ throw new ArgumentException ("blob is too small.");
+
+ try {
+ if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06)
+ (blob [offset+1] != 0x02) || // Version (0x02)
+ (blob [offset+2] != 0x00) || // Reserved (word)
+ (blob [offset+3] != 0x00) ||
+ (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1
+ throw new CryptographicException ("Invalid blob header");
+
+ // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
+ // int algId = ToInt32LE (blob, offset+4);
+
+ // DWORD bitlen
+ int bitLen = ToInt32LE (blob, offset+12);
+
+ // DWORD public exponent
+ RSAParameters rsap = new RSAParameters ();
+ rsap.Exponent = new byte [3];
+ rsap.Exponent [0] = blob [offset+18];
+ rsap.Exponent [1] = blob [offset+17];
+ rsap.Exponent [2] = blob [offset+16];
+
+ int pos = offset+20;
+ // BYTE modulus[rsapubkey.bitlen/8];
+ int byteLen = (bitLen >> 3);
+ rsap.Modulus = new byte [byteLen];
+ Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
+ Array.Reverse (rsap.Modulus);
+ RSA rsa = null;
+ try
+ {
+ rsa = RSA.Create();
+ rsa.ImportParameters(rsap);
+ }
+ catch (CryptographicException)
+ {
+ // this may cause problem when this code is run under
+ // the SYSTEM identity on Windows (e.g. ASP.NET). See
+ // http://bugzilla.ximian.com/show_bug.cgi?id=77559
+ CspParameters csp = new CspParameters();
+ csp.Flags = CspProviderFlags.UseMachineKeyStore;
+ rsa = new RSACryptoServiceProvider(csp);
+ rsa.ImportParameters(rsap);
+ }
+ return rsa;
+ }
+ catch (Exception e) {
+ throw new CryptographicException ("Invalid blob.", e);
+ }
+ }
+
+ static public DSA FromCapiPublicKeyBlobDSA (byte[] blob)
+ {
+ return FromCapiPublicKeyBlobDSA (blob, 0);
+ }
+
+ static public DSA FromCapiPublicKeyBlobDSA (byte[] blob, int offset)
+ {
+ if (blob == null)
+ throw new ArgumentNullException ("blob");
+ if (offset >= blob.Length)
+ throw new ArgumentException ("blob is too small.");
+
+ try {
+ if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06)
+ (blob [offset + 1] != 0x02) || // Version (0x02)
+ (blob [offset + 2] != 0x00) || // Reserved (word)
+ (blob [offset + 3] != 0x00) ||
+ (ToUInt32LE (blob, offset + 8) != 0x31535344)) // DWORD magic
+ throw new CryptographicException ("Invalid blob header");
+
+ int bitlen = ToInt32LE (blob, offset + 12);
+ DSAParameters dsap = new DSAParameters ();
+ int bytelen = bitlen >> 3;
+ int pos = offset + 16;
+
+ dsap.P = new byte [bytelen];
+ Buffer.BlockCopy (blob, pos, dsap.P, 0, bytelen);
+ Array.Reverse (dsap.P);
+ pos += bytelen;
+
+ dsap.Q = new byte [20];
+ Buffer.BlockCopy (blob, pos, dsap.Q, 0, 20);
+ Array.Reverse (dsap.Q);
+ pos += 20;
+
+ dsap.G = new byte [bytelen];
+ Buffer.BlockCopy (blob, pos, dsap.G, 0, bytelen);
+ Array.Reverse (dsap.G);
+ pos += bytelen;
+
+ dsap.Y = new byte [bytelen];
+ Buffer.BlockCopy (blob, pos, dsap.Y, 0, bytelen);
+ Array.Reverse (dsap.Y);
+ pos += bytelen;
+
+ dsap.Counter = ToInt32LE (blob, pos);
+ pos += 4;
+
+ dsap.Seed = new byte [20];
+ Buffer.BlockCopy (blob, pos, dsap.Seed, 0, 20);
+ Array.Reverse (dsap.Seed);
+ pos += 20;
+
+ DSA dsa = (DSA)DSA.Create ();
+ dsa.ImportParameters (dsap);
+ return dsa;
+ }
+ catch (Exception e) {
+ throw new CryptographicException ("Invalid blob.", e);
+ }
+ }
+
+ static public byte[] ToCapiPublicKeyBlob (RSA rsa)
+ {
+ RSAParameters p = rsa.ExportParameters (false);
+ int keyLength = p.Modulus.Length; // in bytes
+ byte[] blob = new byte [20 + keyLength];
+
+ blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06)
+ blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
+ // [2], [3] // RESERVED - Always 0
+ blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
+ blob [8] = 0x52; // Magic - RSA1 (ASCII in hex)
+ blob [9] = 0x53;
+ blob [10] = 0x41;
+ blob [11] = 0x31;
+
+ byte[] bitlen = GetBytesLE (keyLength << 3);
+ blob [12] = bitlen [0]; // bitlen
+ blob [13] = bitlen [1];
+ blob [14] = bitlen [2];
+ blob [15] = bitlen [3];
+
+ // public exponent (DWORD)
+ int pos = 16;
+ int n = p.Exponent.Length;
+ while (n > 0)
+ blob [pos++] = p.Exponent [--n];
+ // modulus
+ pos = 20;
+ byte[] part = p.Modulus;
+ int len = part.Length;
+ Array.Reverse (part, 0, len);
+ Buffer.BlockCopy (part, 0, blob, pos, len);
+ pos += len;
+ return blob;
+ }
+
+ static public byte[] ToCapiPublicKeyBlob (DSA dsa)
+ {
+ DSAParameters p = dsa.ExportParameters (false);
+ int keyLength = p.P.Length; // in bytes
+
+ // header + P + Q + G + Y + count + seed
+ byte[] blob = new byte [16 + keyLength + 20 + keyLength + keyLength + 4 + 20];
+
+ blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06)
+ blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02)
+ // [2], [3] // RESERVED - Always 0
+ blob [5] = 0x22; // ALGID
+ blob [8] = 0x44; // Magic
+ blob [9] = 0x53;
+ blob [10] = 0x53;
+ blob [11] = 0x31;
+
+ byte[] bitlen = GetBytesLE (keyLength << 3);
+ blob [12] = bitlen [0];
+ blob [13] = bitlen [1];
+ blob [14] = bitlen [2];
+ blob [15] = bitlen [3];
+
+ int pos = 16;
+ byte[] part;
+
+ part = p.P;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, keyLength);
+ pos += keyLength;
+
+ part = p.Q;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, 20);
+ pos += 20;
+
+ part = p.G;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, keyLength);
+ pos += keyLength;
+
+ part = p.Y;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, keyLength);
+ pos += keyLength;
+
+ Buffer.BlockCopy (GetBytesLE (p.Counter), 0, blob, pos, 4);
+ pos += 4;
+
+ part = p.Seed;
+ Array.Reverse (part);
+ Buffer.BlockCopy (part, 0, blob, pos, 20);
+
+ return blob;
+ }
+
+ // PRIVATEKEYBLOB
+ // PUBLICKEYBLOB
+ static public RSA FromCapiKeyBlob (byte[] blob)
+ {
+ return FromCapiKeyBlob (blob, 0);
+ }
+
+ static public RSA FromCapiKeyBlob (byte[] blob, int offset)
+ {
+ if (blob == null)
+ throw new ArgumentNullException ("blob");
+ if (offset >= blob.Length)
+ throw new ArgumentException ("blob is too small.");
+
+ switch (blob [offset]) {
+ case 0x00:
+ // this could be a public key inside an header
+ // like "sn -e" would produce
+ if (blob [offset + 12] == 0x06) {
+ return FromCapiPublicKeyBlob (blob, offset + 12);
+ }
+ break;
+ case 0x06:
+ return FromCapiPublicKeyBlob (blob, offset);
+ case 0x07:
+ return FromCapiPrivateKeyBlob (blob, offset);
+ }
+ throw new CryptographicException ("Unknown blob format.");
+ }
+
+ static public DSA FromCapiKeyBlobDSA (byte[] blob)
+ {
+ return FromCapiKeyBlobDSA (blob, 0);
+ }
+
+ static public DSA FromCapiKeyBlobDSA (byte[] blob, int offset)
+ {
+ if (blob == null)
+ throw new ArgumentNullException ("blob");
+ if (offset >= blob.Length)
+ throw new ArgumentException ("blob is too small.");
+
+ switch (blob [offset]) {
+ case 0x06:
+ return FromCapiPublicKeyBlobDSA (blob, offset);
+ case 0x07:
+ return FromCapiPrivateKeyBlobDSA (blob, offset);
+ }
+ throw new CryptographicException ("Unknown blob format.");
+ }
+
+ static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey)
+ {
+ if (keypair == null)
+ throw new ArgumentNullException ("keypair");
+
+ // check between RSA and DSA (and potentially others like DH)
+ if (keypair is RSA)
+ return ToCapiKeyBlob ((RSA)keypair, includePrivateKey);
+ else if (keypair is DSA)
+ return ToCapiKeyBlob ((DSA)keypair, includePrivateKey);
+ else
+ return null; // TODO
+ }
+
+ static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey)
+ {
+ if (rsa == null)
+ throw new ArgumentNullException ("rsa");
+
+ if (includePrivateKey)
+ return ToCapiPrivateKeyBlob (rsa);
+ else
+ return ToCapiPublicKeyBlob (rsa);
+ }
+
+ static public byte[] ToCapiKeyBlob (DSA dsa, bool includePrivateKey)
+ {
+ if (dsa == null)
+ throw new ArgumentNullException ("dsa");
+
+ if (includePrivateKey)
+ return ToCapiPrivateKeyBlob (dsa);
+ else
+ return ToCapiPublicKeyBlob (dsa);
+ }
+
+ static public string ToHex (byte[] input)
+ {
+ if (input == null)
+ return null;
+
+ StringBuilder sb = new StringBuilder (input.Length * 2);
+ foreach (byte b in input) {
+ sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture));
+ }
+ return sb.ToString ();
+ }
+
+ static private byte FromHexChar (char c)
+ {
+ if ((c >= 'a') && (c <= 'f'))
+ return (byte) (c - 'a' + 10);
+ if ((c >= 'A') && (c <= 'F'))
+ return (byte) (c - 'A' + 10);
+ if ((c >= '0') && (c <= '9'))
+ return (byte) (c - '0');
+ throw new ArgumentException ("invalid hex char");
+ }
+
+ static public byte[] FromHex (string hex)
+ {
+ if (hex == null)
+ return null;
+ if ((hex.Length & 0x1) == 0x1)
+ throw new ArgumentException ("Length must be a multiple of 2");
+
+ byte[] result = new byte [hex.Length >> 1];
+ int n = 0;
+ int i = 0;
+ while (n < result.Length) {
+ result [n] = (byte) (FromHexChar (hex [i++]) << 4);
+ result [n++] += FromHexChar (hex [i++]);
+ }
+ return result;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs
new file mode 100644
index 000000000..85bf9db38
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS1.cs
@@ -0,0 +1,491 @@
+//
+// PKCS1.cs - Implements PKCS#1 primitives.
+//
+// Author:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ // References:
+ // a. PKCS#1: RSA Cryptography Standard
+ // http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/index.html
+
+ public sealed class PKCS1 {
+
+ private PKCS1 ()
+ {
+ }
+
+ private static bool Compare (byte[] array1, byte[] array2)
+ {
+ bool result = (array1.Length == array2.Length);
+ if (result) {
+ for (int i=0; i < array1.Length; i++)
+ if (array1[i] != array2[i])
+ return false;
+ }
+ return result;
+ }
+
+ private static byte[] xor (byte[] array1, byte[] array2)
+ {
+ byte[] result = new byte [array1.Length];
+ for (int i=0; i < result.Length; i++)
+ result[i] = (byte) (array1[i] ^ array2[i]);
+ return result;
+ }
+
+ private static byte[] emptySHA1 = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 };
+ private static byte[] emptySHA256 = { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 };
+ private static byte[] emptySHA384 = { 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b };
+ private static byte[] emptySHA512 = { 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e };
+
+ private static byte[] GetEmptyHash (HashAlgorithm hash)
+ {
+ if (hash is SHA1)
+ return emptySHA1;
+ else if (hash is SHA256)
+ return emptySHA256;
+ else if (hash is SHA384)
+ return emptySHA384;
+ else if (hash is SHA512)
+ return emptySHA512;
+ else
+ return hash.ComputeHash ((byte[])null);
+ }
+
+ // PKCS #1 v.2.1, Section 4.1
+ // I2OSP converts a non-negative integer to an octet string of a specified length.
+ public static byte[] I2OSP (int x, int size)
+ {
+ byte[] array = BitConverterLE.GetBytes (x);
+ Array.Reverse (array, 0, array.Length);
+ return I2OSP (array, size);
+ }
+
+ public static byte[] I2OSP (byte[] x, int size)
+ {
+ byte[] result = new byte [size];
+ Buffer.BlockCopy (x, 0, result, (result.Length - x.Length), x.Length);
+ return result;
+ }
+
+ // PKCS #1 v.2.1, Section 4.2
+ // OS2IP converts an octet string to a nonnegative integer.
+ public static byte[] OS2IP (byte[] x)
+ {
+ int i = 0;
+ while ((x [i++] == 0x00) && (i < x.Length)) {
+ // confuse compiler into reporting a warning with {}
+ }
+ i--;
+ if (i > 0) {
+ byte[] result = new byte [x.Length - i];
+ Buffer.BlockCopy (x, i, result, 0, result.Length);
+ return result;
+ }
+ else
+ return x;
+ }
+
+ // PKCS #1 v.2.1, Section 5.1.1
+ public static byte[] RSAEP (RSA rsa, byte[] m)
+ {
+ // c = m^e mod n
+ return rsa.EncryptValue (m);
+ }
+
+ // PKCS #1 v.2.1, Section 5.1.2
+ public static byte[] RSADP (RSA rsa, byte[] c)
+ {
+ // m = c^d mod n
+ // Decrypt value may apply CRT optimizations
+ return rsa.DecryptValue (c);
+ }
+
+ // PKCS #1 v.2.1, Section 5.2.1
+ public static byte[] RSASP1 (RSA rsa, byte[] m)
+ {
+ // first form: s = m^d mod n
+ // Decrypt value may apply CRT optimizations
+ return rsa.DecryptValue (m);
+ }
+
+ // PKCS #1 v.2.1, Section 5.2.2
+ public static byte[] RSAVP1 (RSA rsa, byte[] s)
+ {
+ // m = s^e mod n
+ return rsa.EncryptValue (s);
+ }
+
+ // PKCS #1 v.2.1, Section 7.1.1
+ // RSAES-OAEP-ENCRYPT ((n, e), M, L)
+ public static byte[] Encrypt_OAEP (RSA rsa, HashAlgorithm hash, RandomNumberGenerator rng, byte[] M)
+ {
+ int size = rsa.KeySize / 8;
+ int hLen = hash.HashSize / 8;
+ if (M.Length > size - 2 * hLen - 2)
+ throw new CryptographicException ("message too long");
+ // empty label L SHA1 hash
+ byte[] lHash = GetEmptyHash (hash);
+ int PSLength = (size - M.Length - 2 * hLen - 2);
+ // DB = lHash || PS || 0x01 || M
+ byte[] DB = new byte [lHash.Length + PSLength + 1 + M.Length];
+ Buffer.BlockCopy (lHash, 0, DB, 0, lHash.Length);
+ DB [(lHash.Length + PSLength)] = 0x01;
+ Buffer.BlockCopy (M, 0, DB, (DB.Length - M.Length), M.Length);
+
+ byte[] seed = new byte [hLen];
+ rng.GetBytes (seed);
+
+ byte[] dbMask = MGF1 (hash, seed, size - hLen - 1);
+ byte[] maskedDB = xor (DB, dbMask);
+ byte[] seedMask = MGF1 (hash, maskedDB, hLen);
+ byte[] maskedSeed = xor (seed, seedMask);
+ // EM = 0x00 || maskedSeed || maskedDB
+ byte[] EM = new byte [maskedSeed.Length + maskedDB.Length + 1];
+ Buffer.BlockCopy (maskedSeed, 0, EM, 1, maskedSeed.Length);
+ Buffer.BlockCopy (maskedDB, 0, EM, maskedSeed.Length + 1, maskedDB.Length);
+
+ byte[] m = OS2IP (EM);
+ byte[] c = RSAEP (rsa, m);
+ return I2OSP (c, size);
+ }
+
+ // PKCS #1 v.2.1, Section 7.1.2
+ // RSAES-OAEP-DECRYPT (K, C, L)
+ public static byte[] Decrypt_OAEP (RSA rsa, HashAlgorithm hash, byte[] C)
+ {
+ int size = rsa.KeySize / 8;
+ int hLen = hash.HashSize / 8;
+ if ((size < (2 * hLen + 2)) || (C.Length != size))
+ throw new CryptographicException ("decryption error");
+
+ byte[] c = OS2IP (C);
+ byte[] m = RSADP (rsa, c);
+ byte[] EM = I2OSP (m, size);
+
+ // split EM = Y || maskedSeed || maskedDB
+ byte[] maskedSeed = new byte [hLen];
+ Buffer.BlockCopy (EM, 1, maskedSeed, 0, maskedSeed.Length);
+ byte[] maskedDB = new byte [size - hLen - 1];
+ Buffer.BlockCopy (EM, (EM.Length - maskedDB.Length), maskedDB, 0, maskedDB.Length);
+
+ byte[] seedMask = MGF1 (hash, maskedDB, hLen);
+ byte[] seed = xor (maskedSeed, seedMask);
+ byte[] dbMask = MGF1 (hash, seed, size - hLen - 1);
+ byte[] DB = xor (maskedDB, dbMask);
+
+ byte[] lHash = GetEmptyHash (hash);
+ // split DB = lHash' || PS || 0x01 || M
+ byte[] dbHash = new byte [lHash.Length];
+ Buffer.BlockCopy (DB, 0, dbHash, 0, dbHash.Length);
+ bool h = Compare (lHash, dbHash);
+
+ // find separator 0x01
+ int nPos = lHash.Length;
+ while (DB[nPos] == 0)
+ nPos++;
+
+ int Msize = DB.Length - nPos - 1;
+ byte[] M = new byte [Msize];
+ Buffer.BlockCopy (DB, (nPos + 1), M, 0, Msize);
+
+ // we could have returned EM[0] sooner but would be helping a timing attack
+ if ((EM[0] != 0) || (!h) || (DB[nPos] != 0x01))
+ return null;
+ return M;
+ }
+
+ // PKCS #1 v.2.1, Section 7.2.1
+ // RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M)
+ public static byte[] Encrypt_v15 (RSA rsa, RandomNumberGenerator rng, byte[] M)
+ {
+ int size = rsa.KeySize / 8;
+ if (M.Length > size - 11)
+ throw new CryptographicException ("message too long");
+ int PSLength = System.Math.Max (8, (size - M.Length - 3));
+ byte[] PS = new byte [PSLength];
+ rng.GetNonZeroBytes (PS);
+ byte[] EM = new byte [size];
+ EM [1] = 0x02;
+ Buffer.BlockCopy (PS, 0, EM, 2, PSLength);
+ Buffer.BlockCopy (M, 0, EM, (size - M.Length), M.Length);
+
+ byte[] m = OS2IP (EM);
+ byte[] c = RSAEP (rsa, m);
+ byte[] C = I2OSP (c, size);
+ return C;
+ }
+
+ // PKCS #1 v.2.1, Section 7.2.2
+ // RSAES-PKCS1-V1_5-DECRYPT (K, C)
+ public static byte[] Decrypt_v15 (RSA rsa, byte[] C)
+ {
+ int size = rsa.KeySize >> 3; // div by 8
+ if ((size < 11) || (C.Length > size))
+ throw new CryptographicException ("decryption error");
+ byte[] c = OS2IP (C);
+ byte[] m = RSADP (rsa, c);
+ byte[] EM = I2OSP (m, size);
+
+ if ((EM [0] != 0x00) || (EM [1] != 0x02))
+ return null;
+
+ int mPos = 10;
+ // PS is a minimum of 8 bytes + 2 bytes for header
+ while ((EM [mPos] != 0x00) && (mPos < EM.Length))
+ mPos++;
+ if (EM [mPos] != 0x00)
+ return null;
+ mPos++;
+ byte[] M = new byte [EM.Length - mPos];
+ Buffer.BlockCopy (EM, mPos, M, 0, M.Length);
+ return M;
+ }
+
+ // PKCS #1 v.2.1, Section 8.2.1
+ // RSASSA-PKCS1-V1_5-SIGN (K, M)
+ public static byte[] Sign_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue)
+ {
+ int size = (rsa.KeySize >> 3); // div 8
+ byte[] EM = Encode_v15 (hash, hashValue, size);
+ byte[] m = OS2IP (EM);
+ byte[] s = RSASP1 (rsa, m);
+ byte[] S = I2OSP (s, size);
+ return S;
+ }
+
+ internal static byte[] Sign_v15 (RSA rsa, string hashName, byte[] hashValue)
+ {
+ using (var hash = CreateFromName (hashName))
+ return Sign_v15 (rsa, hash, hashValue);
+ }
+
+ // PKCS #1 v.2.1, Section 8.2.2
+ // RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)
+ public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue, byte[] signature)
+ {
+ return Verify_v15 (rsa, hash, hashValue, signature, false);
+ }
+
+ internal static bool Verify_v15 (RSA rsa, string hashName, byte[] hashValue, byte[] signature)
+ {
+ using (var hash = CreateFromName (hashName))
+ return Verify_v15 (rsa, hash, hashValue, signature, false);
+ }
+
+ // DO NOT USE WITHOUT A VERY GOOD REASON
+ public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte [] hashValue, byte [] signature, bool tryNonStandardEncoding)
+ {
+ int size = (rsa.KeySize >> 3); // div 8
+ byte[] s = OS2IP (signature);
+ byte[] m = RSAVP1 (rsa, s);
+ byte[] EM2 = I2OSP (m, size);
+ byte[] EM = Encode_v15 (hash, hashValue, size);
+ bool result = Compare (EM, EM2);
+ if (result || !tryNonStandardEncoding)
+ return result;
+
+ // NOTE: some signatures don't include the hash OID (pretty lame but real)
+ // and compatible with MS implementation. E.g. Verisign Authenticode Timestamps
+
+ // we're making this "as safe as possible"
+ if ((EM2 [0] != 0x00) || (EM2 [1] != 0x01))
+ return false;
+ int i;
+ for (i = 2; i < EM2.Length - hashValue.Length - 1; i++) {
+ if (EM2 [i] != 0xFF)
+ return false;
+ }
+ if (EM2 [i++] != 0x00)
+ return false;
+
+ byte [] decryptedHash = new byte [hashValue.Length];
+ Buffer.BlockCopy (EM2, i, decryptedHash, 0, decryptedHash.Length);
+ return Compare (decryptedHash, hashValue);
+ }
+
+ // PKCS #1 v.2.1, Section 9.2
+ // EMSA-PKCS1-v1_5-Encode
+ public static byte[] Encode_v15 (HashAlgorithm hash, byte[] hashValue, int emLength)
+ {
+ if (hashValue.Length != (hash.HashSize >> 3))
+ throw new CryptographicException ("bad hash length for " + hash.ToString ());
+
+ // DigestInfo ::= SEQUENCE {
+ // digestAlgorithm AlgorithmIdentifier,
+ // digest OCTET STRING
+ // }
+
+ byte[] t = null;
+
+ string oid = CryptoConfig.MapNameToOID (hash.ToString ());
+ if (oid != null)
+ {
+ ASN1 digestAlgorithm = new ASN1 (0x30);
+ digestAlgorithm.Add (new ASN1 (CryptoConfig.EncodeOID (oid)));
+ digestAlgorithm.Add (new ASN1 (0x05)); // NULL
+ ASN1 digest = new ASN1 (0x04, hashValue);
+ ASN1 digestInfo = new ASN1 (0x30);
+ digestInfo.Add (digestAlgorithm);
+ digestInfo.Add (digest);
+
+ t = digestInfo.GetBytes ();
+ }
+ else
+ {
+ // There are no valid OID, in this case t = hashValue
+ // This is the case of the MD5SHA hash algorithm
+ t = hashValue;
+ }
+
+ Buffer.BlockCopy (hashValue, 0, t, t.Length - hashValue.Length, hashValue.Length);
+
+ int PSLength = System.Math.Max (8, emLength - t.Length - 3);
+ // PS = PSLength of 0xff
+
+ // EM = 0x00 | 0x01 | PS | 0x00 | T
+ byte[] EM = new byte [PSLength + t.Length + 3];
+ EM [1] = 0x01;
+ for (int i=2; i < PSLength + 2; i++)
+ EM[i] = 0xff;
+ Buffer.BlockCopy (t, 0, EM, PSLength + 3, t.Length);
+
+ return EM;
+ }
+
+ // PKCS #1 v.2.1, Section B.2.1
+ public static byte[] MGF1 (HashAlgorithm hash, byte[] mgfSeed, int maskLen)
+ {
+ // 1. If maskLen > 2^32 hLen, output "mask too long" and stop.
+ // easy - this is impossible by using a int (31bits) as parameter ;-)
+ // BUT with a signed int we do have to check for negative values!
+ if (maskLen < 0)
+ throw new OverflowException();
+
+ int mgfSeedLength = mgfSeed.Length;
+ int hLen = (hash.HashSize >> 3); // from bits to bytes
+ int iterations = (maskLen / hLen);
+ if (maskLen % hLen != 0)
+ iterations++;
+ // 2. Let T be the empty octet string.
+ byte[] T = new byte [iterations * hLen];
+
+ byte[] toBeHashed = new byte [mgfSeedLength + 4];
+ int pos = 0;
+ // 3. For counter from 0 to \ceil (maskLen / hLen) - 1, do the following:
+ for (int counter = 0; counter < iterations; counter++) {
+ // a. Convert counter to an octet string C of length 4 octets
+ byte[] C = I2OSP (counter, 4);
+
+ // b. Concatenate the hash of the seed mgfSeed and C to the octet string T:
+ // T = T || Hash (mgfSeed || C)
+ Buffer.BlockCopy (mgfSeed, 0, toBeHashed, 0, mgfSeedLength);
+ Buffer.BlockCopy (C, 0, toBeHashed, mgfSeedLength, 4);
+ byte[] output = hash.ComputeHash (toBeHashed);
+ Buffer.BlockCopy (output, 0, T, pos, hLen);
+ pos += hLen;
+ }
+
+ // 4. Output the leading maskLen octets of T as the octet string mask.
+ byte[] mask = new byte [maskLen];
+ Buffer.BlockCopy (T, 0, mask, 0, maskLen);
+ return mask;
+ }
+
+ static internal string HashNameFromOid (string oid, bool throwOnError = true)
+ {
+ switch (oid) {
+ case "1.2.840.113549.1.1.2": // MD2 with RSA encryption
+ return "MD2";
+ case "1.2.840.113549.1.1.3": // MD4 with RSA encryption
+ return "MD4";
+ case "1.2.840.113549.1.1.4": // MD5 with RSA encryption
+ return "MD5";
+ case "1.2.840.113549.1.1.5": // SHA-1 with RSA Encryption
+ case "1.3.14.3.2.29": // SHA1 with RSA signature
+ case "1.2.840.10040.4.3": // SHA1-1 with DSA
+ return "SHA1";
+ case "1.2.840.113549.1.1.11": // SHA-256 with RSA Encryption
+ return "SHA256";
+ case "1.2.840.113549.1.1.12": // SHA-384 with RSA Encryption
+ return "SHA384";
+ case "1.2.840.113549.1.1.13": // SHA-512 with RSA Encryption
+ return "SHA512";
+ case "1.3.36.3.3.1.2":
+ return "RIPEMD160";
+ default:
+ if (throwOnError)
+ throw new CryptographicException ("Unsupported hash algorithm: " + oid);
+ return null;
+ }
+ }
+
+ static internal HashAlgorithm CreateFromOid (string oid)
+ {
+ return CreateFromName (HashNameFromOid (oid));
+ }
+
+ static internal HashAlgorithm CreateFromName (string name)
+ {
+#if FULL_AOT_RUNTIME
+ switch (name) {
+ case "MD2":
+ return MD2.Create ();
+ case "MD4":
+ return MD4.Create ();
+ case "MD5":
+ return MD5.Create ();
+ case "SHA1":
+ return SHA1.Create ();
+ case "SHA256":
+ return SHA256.Create ();
+ case "SHA384":
+ return SHA384.Create ();
+ case "SHA512":
+ return SHA512.Create ();
+ case "RIPEMD160":
+ return RIPEMD160.Create ();
+ default:
+ try {
+ return (HashAlgorithm) Activator.CreateInstance (Type.GetType (name));
+ }
+ catch {
+ throw new CryptographicException ("Unsupported hash algorithm: " + name);
+ }
+ }
+#else
+ return HashAlgorithm.Create (name);
+#endif
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs
new file mode 100644
index 000000000..2205a7160
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS12.cs
@@ -0,0 +1,1934 @@
+//
+// PKCS12.cs: PKCS 12 - Personal Information Exchange Syntax
+//
+// Author:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004,2005,2006 Novell Inc. (http://www.novell.com)
+// Copyright 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Key derivation translated from Bouncy Castle JCE (http://www.bouncycastle.org/)
+// See bouncycastle.txt for license.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ public class PKCS5 {
+
+ public const string pbeWithMD2AndDESCBC = "1.2.840.113549.1.5.1";
+ public const string pbeWithMD5AndDESCBC = "1.2.840.113549.1.5.3";
+ public const string pbeWithMD2AndRC2CBC = "1.2.840.113549.1.5.4";
+ public const string pbeWithMD5AndRC2CBC = "1.2.840.113549.1.5.6";
+ public const string pbeWithSHA1AndDESCBC = "1.2.840.113549.1.5.10";
+ public const string pbeWithSHA1AndRC2CBC = "1.2.840.113549.1.5.11";
+
+ public PKCS5 () {}
+ }
+
+ public class PKCS9 {
+
+ public const string friendlyName = "1.2.840.113549.1.9.20";
+ public const string localKeyId = "1.2.840.113549.1.9.21";
+
+ public PKCS9 () {}
+ }
+
+
+ internal class SafeBag {
+ private string _bagOID;
+ private ASN1 _asn1;
+
+ public SafeBag(string bagOID, ASN1 asn1) {
+ _bagOID = bagOID;
+ _asn1 = asn1;
+ }
+
+ public string BagOID {
+ get { return _bagOID; }
+ }
+
+ public ASN1 ASN1 {
+ get { return _asn1; }
+ }
+ }
+
+
+ public class PKCS12 : ICloneable {
+
+ public const string pbeWithSHAAnd128BitRC4 = "1.2.840.113549.1.12.1.1";
+ public const string pbeWithSHAAnd40BitRC4 = "1.2.840.113549.1.12.1.2";
+ public const string pbeWithSHAAnd3KeyTripleDESCBC = "1.2.840.113549.1.12.1.3";
+ public const string pbeWithSHAAnd2KeyTripleDESCBC = "1.2.840.113549.1.12.1.4";
+ public const string pbeWithSHAAnd128BitRC2CBC = "1.2.840.113549.1.12.1.5";
+ public const string pbeWithSHAAnd40BitRC2CBC = "1.2.840.113549.1.12.1.6";
+
+ // bags
+ public const string keyBag = "1.2.840.113549.1.12.10.1.1";
+ public const string pkcs8ShroudedKeyBag = "1.2.840.113549.1.12.10.1.2";
+ public const string certBag = "1.2.840.113549.1.12.10.1.3";
+ public const string crlBag = "1.2.840.113549.1.12.10.1.4";
+ public const string secretBag = "1.2.840.113549.1.12.10.1.5";
+ public const string safeContentsBag = "1.2.840.113549.1.12.10.1.6";
+
+ // types
+ public const string x509Certificate = "1.2.840.113549.1.9.22.1";
+ public const string sdsiCertificate = "1.2.840.113549.1.9.22.2";
+ public const string x509Crl = "1.2.840.113549.1.9.23.1";
+
+ // Adapted from BouncyCastle PKCS12ParametersGenerator.java
+ public class DeriveBytes {
+
+ public enum Purpose {
+ Key,
+ IV,
+ MAC
+ }
+
+ static private byte[] keyDiversifier = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
+ static private byte[] ivDiversifier = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 };
+ static private byte[] macDiversifier = { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 };
+
+ private string _hashName;
+ private int _iterations;
+ private byte[] _password;
+ private byte[] _salt;
+
+ public DeriveBytes () {}
+
+ public string HashName {
+ get { return _hashName; }
+ set { _hashName = value; }
+ }
+
+ public int IterationCount {
+ get { return _iterations; }
+ set { _iterations = value; }
+ }
+
+ public byte[] Password {
+ get { return (byte[]) _password.Clone (); }
+ set {
+ if (value == null)
+ _password = new byte [0];
+ else
+ _password = (byte[]) value.Clone ();
+ }
+ }
+
+ public byte[] Salt {
+ get { return (byte[]) _salt.Clone (); }
+ set {
+ if (value != null)
+ _salt = (byte[]) value.Clone ();
+ else
+ _salt = null;
+ }
+ }
+
+ private void Adjust (byte[] a, int aOff, byte[] b)
+ {
+ int x = (b[b.Length - 1] & 0xff) + (a [aOff + b.Length - 1] & 0xff) + 1;
+
+ a [aOff + b.Length - 1] = (byte) x;
+ x >>= 8;
+
+ for (int i = b.Length - 2; i >= 0; i--) {
+ x += (b [i] & 0xff) + (a [aOff + i] & 0xff);
+ a [aOff + i] = (byte) x;
+ x >>= 8;
+ }
+ }
+
+ private byte[] Derive (byte[] diversifier, int n)
+ {
+ HashAlgorithm digest = PKCS1.CreateFromName (_hashName);
+ int u = (digest.HashSize >> 3); // div 8
+ int v = 64;
+ byte[] dKey = new byte [n];
+
+ byte[] S;
+ if ((_salt != null) && (_salt.Length != 0)) {
+ S = new byte[v * ((_salt.Length + v - 1) / v)];
+
+ for (int i = 0; i != S.Length; i++) {
+ S[i] = _salt[i % _salt.Length];
+ }
+ }
+ else {
+ S = new byte[0];
+ }
+
+ byte[] P;
+ if ((_password != null) && (_password.Length != 0)) {
+ P = new byte[v * ((_password.Length + v - 1) / v)];
+
+ for (int i = 0; i != P.Length; i++) {
+ P[i] = _password[i % _password.Length];
+ }
+ }
+ else {
+ P = new byte[0];
+ }
+
+ byte[] I = new byte [S.Length + P.Length];
+
+ Buffer.BlockCopy (S, 0, I, 0, S.Length);
+ Buffer.BlockCopy (P, 0, I, S.Length, P.Length);
+
+ byte[] B = new byte[v];
+ int c = (n + u - 1) / u;
+
+ for (int i = 1; i <= c; i++) {
+ digest.TransformBlock (diversifier, 0, diversifier.Length, diversifier, 0);
+ digest.TransformFinalBlock (I, 0, I.Length);
+ byte[] A = digest.Hash;
+ digest.Initialize ();
+ for (int j = 1; j != _iterations; j++) {
+ A = digest.ComputeHash (A, 0, A.Length);
+ }
+
+ for (int j = 0; j != B.Length; j++) {
+ B [j] = A [j % A.Length];
+ }
+
+ for (int j = 0; j != I.Length / v; j++) {
+ Adjust (I, j * v, B);
+ }
+
+ if (i == c) {
+ Buffer.BlockCopy(A, 0, dKey, (i - 1) * u, dKey.Length - ((i - 1) * u));
+ }
+ else {
+ Buffer.BlockCopy(A, 0, dKey, (i - 1) * u, A.Length);
+ }
+ }
+
+ return dKey;
+ }
+
+ public byte[] DeriveKey (int size)
+ {
+ return Derive (keyDiversifier, size);
+ }
+
+ public byte[] DeriveIV (int size)
+ {
+ return Derive (ivDiversifier, size);
+ }
+
+ public byte[] DeriveMAC (int size)
+ {
+ return Derive (macDiversifier, size);
+ }
+ }
+
+ const int recommendedIterationCount = 2000;
+
+ //private int _version;
+ private byte[] _password;
+ private ArrayList _keyBags;
+ private ArrayList _secretBags;
+ private X509CertificateCollection _certs;
+ private bool _keyBagsChanged;
+ private bool _secretBagsChanged;
+ private bool _certsChanged;
+ private int _iterations;
+ private ArrayList _safeBags;
+ private RandomNumberGenerator _rng;
+
+ // constructors
+
+ public PKCS12 ()
+ {
+ _iterations = recommendedIterationCount;
+ _keyBags = new ArrayList ();
+ _secretBags = new ArrayList ();
+ _certs = new X509CertificateCollection ();
+ _keyBagsChanged = false;
+ _secretBagsChanged = false;
+ _certsChanged = false;
+ _safeBags = new ArrayList ();
+ }
+
+ public PKCS12 (byte[] data)
+ : this ()
+ {
+ Password = null;
+ Decode (data);
+ }
+
+ /*
+ * PFX ::= SEQUENCE {
+ * version INTEGER {v3(3)}(v3,...),
+ * authSafe ContentInfo,
+ * macData MacData OPTIONAL
+ * }
+ *
+ * MacData ::= SEQUENCE {
+ * mac DigestInfo,
+ * macSalt OCTET STRING,
+ * iterations INTEGER DEFAULT 1
+ * -- Note: The default is for historical reasons and its use is deprecated. A higher
+ * -- value, like 1024 is recommended.
+ * }
+ *
+ * SafeContents ::= SEQUENCE OF SafeBag
+ *
+ * SafeBag ::= SEQUENCE {
+ * bagId BAG-TYPE.&id ({PKCS12BagSet}),
+ * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
+ * bagAttributes SET OF PKCS12Attribute OPTIONAL
+ * }
+ */
+ public PKCS12 (byte[] data, string password)
+ : this ()
+ {
+ Password = password;
+ Decode (data);
+ }
+
+ public PKCS12 (byte[] data, byte[] password)
+ : this ()
+ {
+ _password = password;
+ Decode (data);
+ }
+
+ private void Decode (byte[] data)
+ {
+ ASN1 pfx = new ASN1 (data);
+ if (pfx.Tag != 0x30)
+ throw new ArgumentException ("invalid data");
+
+ ASN1 version = pfx [0];
+ if (version.Tag != 0x02)
+ throw new ArgumentException ("invalid PFX version");
+ //_version = version.Value [0];
+
+ PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (pfx [1]);
+ if (authSafe.ContentType != PKCS7.Oid.data)
+ throw new ArgumentException ("invalid authenticated safe");
+
+ // now that we know it's a PKCS#12 file, check the (optional) MAC
+ // before decoding anything else in the file
+ if (pfx.Count > 2) {
+ ASN1 macData = pfx [2];
+ if (macData.Tag != 0x30)
+ throw new ArgumentException ("invalid MAC");
+
+ ASN1 mac = macData [0];
+ if (mac.Tag != 0x30)
+ throw new ArgumentException ("invalid MAC");
+ ASN1 macAlgorithm = mac [0];
+ string macOid = ASN1Convert.ToOid (macAlgorithm [0]);
+ if (macOid != "1.3.14.3.2.26")
+ throw new ArgumentException ("unsupported HMAC");
+ byte[] macValue = mac [1].Value;
+
+ ASN1 macSalt = macData [1];
+ if (macSalt.Tag != 0x04)
+ throw new ArgumentException ("missing MAC salt");
+
+ _iterations = 1; // default value
+ if (macData.Count > 2) {
+ ASN1 iters = macData [2];
+ if (iters.Tag != 0x02)
+ throw new ArgumentException ("invalid MAC iteration");
+ _iterations = ASN1Convert.ToInt32 (iters);
+ }
+
+ byte[] authSafeData = authSafe.Content [0].Value;
+ byte[] calculatedMac = MAC (_password, macSalt.Value, _iterations, authSafeData);
+ if (!Compare (macValue, calculatedMac)) {
+ byte[] nullPassword = {0, 0};
+ calculatedMac = MAC(nullPassword, macSalt.Value, _iterations, authSafeData);
+ if (!Compare (macValue, calculatedMac))
+ throw new CryptographicException ("Invalid MAC - file may have been tampe red!");
+ _password = nullPassword;
+ }
+ }
+
+ // we now returns to our original presentation - PFX
+ ASN1 authenticatedSafe = new ASN1 (authSafe.Content [0].Value);
+ for (int i=0; i < authenticatedSafe.Count; i++) {
+ PKCS7.ContentInfo ci = new PKCS7.ContentInfo (authenticatedSafe [i]);
+ switch (ci.ContentType) {
+ case PKCS7.Oid.data:
+ // unencrypted (by PKCS#12)
+ ASN1 safeContents = new ASN1 (ci.Content [0].Value);
+ for (int j=0; j < safeContents.Count; j++) {
+ ASN1 safeBag = safeContents [j];
+ ReadSafeBag (safeBag);
+ }
+ break;
+ case PKCS7.Oid.encryptedData:
+ // password encrypted
+ PKCS7.EncryptedData ed = new PKCS7.EncryptedData (ci.Content [0]);
+ ASN1 decrypted = new ASN1 (Decrypt (ed));
+ for (int j=0; j < decrypted.Count; j++) {
+ ASN1 safeBag = decrypted [j];
+ ReadSafeBag (safeBag);
+ }
+ break;
+ case PKCS7.Oid.envelopedData:
+ // public key encrypted
+ throw new NotImplementedException ("public key encrypted");
+ default:
+ throw new ArgumentException ("unknown authenticatedSafe");
+ }
+ }
+ }
+
+ ~PKCS12 ()
+ {
+ if (_password != null) {
+ Array.Clear (_password, 0, _password.Length);
+ }
+ _password = null;
+ }
+
+ // properties
+
+ public string Password {
+ set {
+ // Clear old password.
+ if (_password != null)
+ Array.Clear (_password, 0, _password.Length);
+ _password = null;
+ if (value != null) {
+ if (value.Length > 0) {
+ int size = value.Length;
+ int nul = 0;
+ if (size < MaximumPasswordLength) {
+ // if not present, add space for a NULL (0x00) character
+ if (value[size - 1] != 0x00)
+ nul = 1;
+ } else {
+ size = MaximumPasswordLength;
+ }
+ _password = new byte[(size + nul) << 1]; // double for unicode
+ Encoding.BigEndianUnicode.GetBytes (value, 0, size, _password, 0);
+ } else {
+ // double-byte (Unicode) NULL (0x00) - see bug #79617
+ _password = new byte[2];
+ }
+ }
+ }
+ }
+
+ public int IterationCount {
+ get { return _iterations; }
+ set { _iterations = value; }
+ }
+
+ public ArrayList Keys {
+ get {
+ if (_keyBagsChanged) {
+ _keyBags.Clear ();
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (keyBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value);
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p));
+ break;
+ case 0x30:
+ _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey));
+ break;
+ default:
+ break;
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+
+ } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
+ byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted);
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p));
+ break;
+ case 0x30:
+ _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey));
+ break;
+ default:
+ break;
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+ Array.Clear (decrypted, 0, decrypted.Length);
+ }
+ }
+ _keyBagsChanged = false;
+ }
+ return ArrayList.ReadOnly(_keyBags);
+ }
+ }
+
+ public ArrayList Secrets {
+ get {
+ if (_secretBagsChanged) {
+ _secretBags.Clear ();
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (secretBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ byte[] secret = bagValue.Value;
+ _secretBags.Add(secret);
+ }
+ }
+ _secretBagsChanged = false;
+ }
+ return ArrayList.ReadOnly(_secretBags);
+ }
+ }
+
+ public X509CertificateCollection Certificates {
+ get {
+ if (_certsChanged) {
+ _certs.Clear ();
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (certBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value);
+ _certs.Add (new X509Certificate (cert.Content [0].Value));
+ }
+ }
+ _certsChanged = false;
+ }
+ return _certs;
+ }
+ }
+
+ internal RandomNumberGenerator RNG {
+ get {
+ if (_rng == null)
+ _rng = RandomNumberGenerator.Create ();
+ return _rng;
+ }
+ }
+
+ // private methods
+
+ private bool Compare (byte[] expected, byte[] actual)
+ {
+ bool compare = false;
+ if (expected.Length == actual.Length) {
+ for (int i=0; i < expected.Length; i++) {
+ if (expected [i] != actual [i])
+ return false;
+ }
+ compare = true;
+ }
+ return compare;
+ }
+
+ private SymmetricAlgorithm GetSymmetricAlgorithm (string algorithmOid, byte[] salt, int iterationCount)
+ {
+ string algorithm = null;
+ int keyLength = 8; // 64 bits (default)
+ int ivLength = 8; // 64 bits (default)
+
+ PKCS12.DeriveBytes pd = new PKCS12.DeriveBytes ();
+ pd.Password = _password;
+ pd.Salt = salt;
+ pd.IterationCount = iterationCount;
+
+ switch (algorithmOid) {
+ case PKCS5.pbeWithMD2AndDESCBC: // no unit test available
+ pd.HashName = "MD2";
+ algorithm = "DES";
+ break;
+ case PKCS5.pbeWithMD5AndDESCBC: // no unit test available
+ pd.HashName = "MD5";
+ algorithm = "DES";
+ break;
+ case PKCS5.pbeWithMD2AndRC2CBC: // no unit test available
+ // TODO - RC2-CBC-Parameter (PKCS5)
+ // if missing default to 32 bits !!!
+ pd.HashName = "MD2";
+ algorithm = "RC2";
+ keyLength = 4; // default
+ break;
+ case PKCS5.pbeWithMD5AndRC2CBC: // no unit test available
+ // TODO - RC2-CBC-Parameter (PKCS5)
+ // if missing default to 32 bits !!!
+ pd.HashName = "MD5";
+ algorithm = "RC2";
+ keyLength = 4; // default
+ break;
+ case PKCS5.pbeWithSHA1AndDESCBC: // no unit test available
+ pd.HashName = "SHA1";
+ algorithm = "DES";
+ break;
+ case PKCS5.pbeWithSHA1AndRC2CBC: // no unit test available
+ // TODO - RC2-CBC-Parameter (PKCS5)
+ // if missing default to 32 bits !!!
+ pd.HashName = "SHA1";
+ algorithm = "RC2";
+ keyLength = 4; // default
+ break;
+ case PKCS12.pbeWithSHAAnd128BitRC4: // no unit test available
+ pd.HashName = "SHA1";
+ algorithm = "RC4";
+ keyLength = 16;
+ ivLength = 0; // N/A
+ break;
+ case PKCS12.pbeWithSHAAnd40BitRC4: // no unit test available
+ pd.HashName = "SHA1";
+ algorithm = "RC4";
+ keyLength = 5;
+ ivLength = 0; // N/A
+ break;
+ case PKCS12.pbeWithSHAAnd3KeyTripleDESCBC:
+ pd.HashName = "SHA1";
+ algorithm = "TripleDES";
+ keyLength = 24;
+ break;
+ case PKCS12.pbeWithSHAAnd2KeyTripleDESCBC: // no unit test available
+ pd.HashName = "SHA1";
+ algorithm = "TripleDES";
+ keyLength = 16;
+ break;
+ case PKCS12.pbeWithSHAAnd128BitRC2CBC: // no unit test available
+ pd.HashName = "SHA1";
+ algorithm = "RC2";
+ keyLength = 16;
+ break;
+ case PKCS12.pbeWithSHAAnd40BitRC2CBC:
+ pd.HashName = "SHA1";
+ algorithm = "RC2";
+ keyLength = 5;
+ break;
+ default:
+ throw new NotSupportedException ("unknown oid " + algorithm);
+ }
+
+ SymmetricAlgorithm sa = null;
+ sa = SymmetricAlgorithm.Create(algorithm);
+ sa.Key = pd.DeriveKey (keyLength);
+ // IV required only for block ciphers (not stream ciphers)
+ if (ivLength > 0) {
+ sa.IV = pd.DeriveIV (ivLength);
+ sa.Mode = CipherMode.CBC;
+ }
+ return sa;
+ }
+
+ public byte[] Decrypt (string algorithmOid, byte[] salt, int iterationCount, byte[] encryptedData)
+ {
+ SymmetricAlgorithm sa = null;
+ byte[] result = null;
+ try {
+ sa = GetSymmetricAlgorithm (algorithmOid, salt, iterationCount);
+ ICryptoTransform ct = sa.CreateDecryptor ();
+ result = ct.TransformFinalBlock (encryptedData, 0, encryptedData.Length);
+ }
+ finally {
+ if (sa != null)
+ sa.Clear ();
+ }
+ return result;
+ }
+
+ public byte[] Decrypt (PKCS7.EncryptedData ed)
+ {
+ return Decrypt (ed.EncryptionAlgorithm.ContentType,
+ ed.EncryptionAlgorithm.Content [0].Value,
+ ASN1Convert.ToInt32 (ed.EncryptionAlgorithm.Content [1]),
+ ed.EncryptedContent);
+ }
+
+ public byte[] Encrypt (string algorithmOid, byte[] salt, int iterationCount, byte[] data)
+ {
+ byte[] result = null;
+ using (SymmetricAlgorithm sa = GetSymmetricAlgorithm (algorithmOid, salt, iterationCount)) {
+ ICryptoTransform ct = sa.CreateEncryptor ();
+ result = ct.TransformFinalBlock (data, 0, data.Length);
+ }
+ return result;
+ }
+
+ private DSAParameters GetExistingParameters (out bool found)
+ {
+ foreach (X509Certificate cert in Certificates) {
+ // FIXME: that won't work if parts of the parameters are missing
+ if (cert.KeyAlgorithmParameters != null) {
+ DSA dsa = cert.DSA;
+ if (dsa != null) {
+ found = true;
+ return dsa.ExportParameters (false);
+ }
+ }
+ }
+ found = false;
+ return new DSAParameters ();
+ }
+
+ private void AddPrivateKey (PKCS8.PrivateKeyInfo pki)
+ {
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ bool found;
+ DSAParameters p = GetExistingParameters (out found);
+ if (found) {
+ _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p));
+ }
+ break;
+ case 0x30:
+ _keyBags.Add (PKCS8.PrivateKeyInfo.DecodeRSA (privateKey));
+ break;
+ default:
+ Array.Clear (privateKey, 0, privateKey.Length);
+ throw new CryptographicException ("Unknown private key format");
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+ }
+
+ private void ReadSafeBag (ASN1 safeBag)
+ {
+ if (safeBag.Tag != 0x30)
+ throw new ArgumentException ("invalid safeBag");
+
+ ASN1 bagId = safeBag [0];
+ if (bagId.Tag != 0x06)
+ throw new ArgumentException ("invalid safeBag id");
+
+ ASN1 bagValue = safeBag [1];
+ string oid = ASN1Convert.ToOid (bagId);
+ switch (oid) {
+ case keyBag:
+ // NEED UNIT TEST
+ AddPrivateKey (new PKCS8.PrivateKeyInfo (bagValue.Value));
+ break;
+ case pkcs8ShroudedKeyBag:
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
+ byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
+ AddPrivateKey (new PKCS8.PrivateKeyInfo (decrypted));
+ Array.Clear (decrypted, 0, decrypted.Length);
+ break;
+ case certBag:
+ PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value);
+ if (cert.ContentType != x509Certificate)
+ throw new NotSupportedException ("unsupport certificate type");
+ X509Certificate x509 = new X509Certificate (cert.Content [0].Value);
+ _certs.Add (x509);
+ break;
+ case crlBag:
+ // TODO
+ break;
+ case secretBag:
+ byte[] secret = bagValue.Value;
+ _secretBags.Add(secret);
+ break;
+ case safeContentsBag:
+ // TODO - ? recurse ?
+ break;
+ default:
+ throw new ArgumentException ("unknown safeBag oid");
+ }
+
+ if (safeBag.Count > 2) {
+ ASN1 bagAttributes = safeBag [2];
+ if (bagAttributes.Tag != 0x31)
+ throw new ArgumentException ("invalid safeBag attributes id");
+
+ for (int i = 0; i < bagAttributes.Count; i++) {
+ ASN1 pkcs12Attribute = bagAttributes[i];
+
+ if (pkcs12Attribute.Tag != 0x30)
+ throw new ArgumentException ("invalid PKCS12 attributes id");
+
+ ASN1 attrId = pkcs12Attribute [0];
+ if (attrId.Tag != 0x06)
+ throw new ArgumentException ("invalid attribute id");
+
+ string attrOid = ASN1Convert.ToOid (attrId);
+
+ ASN1 attrValues = pkcs12Attribute[1];
+ for (int j = 0; j < attrValues.Count; j++) {
+ ASN1 attrValue = attrValues[j];
+
+ switch (attrOid) {
+ case PKCS9.friendlyName:
+ if (attrValue.Tag != 0x1e)
+ throw new ArgumentException ("invalid attribute value id");
+ break;
+ case PKCS9.localKeyId:
+ if (attrValue.Tag != 0x04)
+ throw new ArgumentException ("invalid attribute value id");
+ break;
+ default:
+ // Unknown OID -- don't check Tag
+ break;
+ }
+ }
+ }
+ }
+
+ _safeBags.Add (new SafeBag(oid, safeBag));
+ }
+
+ private ASN1 Pkcs8ShroudedKeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes)
+ {
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo ();
+ if (aa is RSA) {
+ pki.Algorithm = "1.2.840.113549.1.1.1";
+ pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa);
+ }
+ else if (aa is DSA) {
+ pki.Algorithm = null;
+ pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa);
+ }
+ else
+ throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ());
+
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo ();
+ epki.Algorithm = pbeWithSHAAnd3KeyTripleDESCBC;
+ epki.IterationCount = _iterations;
+ epki.EncryptedData = Encrypt (pbeWithSHAAnd3KeyTripleDESCBC, epki.Salt, _iterations, pki.GetBytes ());
+
+ ASN1 safeBag = new ASN1 (0x30);
+ safeBag.Add (ASN1Convert.FromOid (pkcs8ShroudedKeyBag));
+ ASN1 bagValue = new ASN1 (0xA0);
+ bagValue.Add (new ASN1 (epki.GetBytes ()));
+ safeBag.Add (bagValue);
+
+ if (attributes != null) {
+ ASN1 bagAttributes = new ASN1 (0x31);
+ IDictionaryEnumerator de = attributes.GetEnumerator ();
+
+ while (de.MoveNext ()) {
+ string oid = (string)de.Key;
+ switch (oid) {
+ case PKCS9.friendlyName:
+ ArrayList names = (ArrayList)de.Value;
+ if (names.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] name in names) {
+ ASN1 attrValue = new ASN1 (0x1e);
+ attrValue.Value = name;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ case PKCS9.localKeyId:
+ ArrayList keys = (ArrayList)de.Value;
+ if (keys.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] key in keys) {
+ ASN1 attrValue = new ASN1 (0x04);
+ attrValue.Value = key;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (bagAttributes.Count > 0) {
+ safeBag.Add (bagAttributes);
+ }
+ }
+
+ return safeBag;
+ }
+
+ private ASN1 KeyBagSafeBag (AsymmetricAlgorithm aa, IDictionary attributes)
+ {
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo ();
+ if (aa is RSA) {
+ pki.Algorithm = "1.2.840.113549.1.1.1";
+ pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((RSA)aa);
+ }
+ else if (aa is DSA) {
+ pki.Algorithm = null;
+ pki.PrivateKey = PKCS8.PrivateKeyInfo.Encode ((DSA)aa);
+ }
+ else
+ throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ());
+
+ ASN1 safeBag = new ASN1 (0x30);
+ safeBag.Add (ASN1Convert.FromOid (keyBag));
+ ASN1 bagValue = new ASN1 (0xA0);
+ bagValue.Add (new ASN1 (pki.GetBytes ()));
+ safeBag.Add (bagValue);
+
+ if (attributes != null) {
+ ASN1 bagAttributes = new ASN1 (0x31);
+ IDictionaryEnumerator de = attributes.GetEnumerator ();
+
+ while (de.MoveNext ()) {
+ string oid = (string)de.Key;
+ switch (oid) {
+ case PKCS9.friendlyName:
+ ArrayList names = (ArrayList)de.Value;
+ if (names.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] name in names) {
+ ASN1 attrValue = new ASN1 (0x1e);
+ attrValue.Value = name;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ case PKCS9.localKeyId:
+ ArrayList keys = (ArrayList)de.Value;
+ if (keys.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] key in keys) {
+ ASN1 attrValue = new ASN1 (0x04);
+ attrValue.Value = key;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (bagAttributes.Count > 0) {
+ safeBag.Add (bagAttributes);
+ }
+ }
+
+ return safeBag;
+ }
+
+ private ASN1 SecretBagSafeBag (byte[] secret, IDictionary attributes)
+ {
+ ASN1 safeBag = new ASN1 (0x30);
+ safeBag.Add (ASN1Convert.FromOid (secretBag));
+ ASN1 bagValue = new ASN1 (0x80, secret);
+ safeBag.Add (bagValue);
+
+ if (attributes != null) {
+ ASN1 bagAttributes = new ASN1 (0x31);
+ IDictionaryEnumerator de = attributes.GetEnumerator ();
+
+ while (de.MoveNext ()) {
+ string oid = (string)de.Key;
+ switch (oid) {
+ case PKCS9.friendlyName:
+ ArrayList names = (ArrayList)de.Value;
+ if (names.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] name in names) {
+ ASN1 attrValue = new ASN1 (0x1e);
+ attrValue.Value = name;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ case PKCS9.localKeyId:
+ ArrayList keys = (ArrayList)de.Value;
+ if (keys.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] key in keys) {
+ ASN1 attrValue = new ASN1 (0x04);
+ attrValue.Value = key;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (bagAttributes.Count > 0) {
+ safeBag.Add (bagAttributes);
+ }
+ }
+
+ return safeBag;
+ }
+
+ private ASN1 CertificateSafeBag (X509Certificate x509, IDictionary attributes)
+ {
+ ASN1 encapsulatedCertificate = new ASN1 (0x04, x509.RawData);
+
+ PKCS7.ContentInfo ci = new PKCS7.ContentInfo ();
+ ci.ContentType = x509Certificate;
+ ci.Content.Add (encapsulatedCertificate);
+
+ ASN1 bagValue = new ASN1 (0xA0);
+ bagValue.Add (ci.ASN1);
+
+ ASN1 safeBag = new ASN1 (0x30);
+ safeBag.Add (ASN1Convert.FromOid (certBag));
+ safeBag.Add (bagValue);
+
+ if (attributes != null) {
+ ASN1 bagAttributes = new ASN1 (0x31);
+ IDictionaryEnumerator de = attributes.GetEnumerator ();
+
+ while (de.MoveNext ()) {
+ string oid = (string)de.Key;
+ switch (oid) {
+ case PKCS9.friendlyName:
+ ArrayList names = (ArrayList)de.Value;
+ if (names.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.friendlyName));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] name in names) {
+ ASN1 attrValue = new ASN1 (0x1e);
+ attrValue.Value = name;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ case PKCS9.localKeyId:
+ ArrayList keys = (ArrayList)de.Value;
+ if (keys.Count > 0) {
+ ASN1 pkcs12Attribute = new ASN1 (0x30);
+ pkcs12Attribute.Add (ASN1Convert.FromOid (PKCS9.localKeyId));
+ ASN1 attrValues = new ASN1 (0x31);
+ foreach (byte[] key in keys) {
+ ASN1 attrValue = new ASN1 (0x04);
+ attrValue.Value = key;
+ attrValues.Add (attrValue);
+ }
+ pkcs12Attribute.Add (attrValues);
+ bagAttributes.Add (pkcs12Attribute);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (bagAttributes.Count > 0) {
+ safeBag.Add (bagAttributes);
+ }
+ }
+
+ return safeBag;
+ }
+
+ private byte[] MAC (byte[] password, byte[] salt, int iterations, byte[] data)
+ {
+ PKCS12.DeriveBytes pd = new PKCS12.DeriveBytes ();
+ pd.HashName = "SHA1";
+ pd.Password = password;
+ pd.Salt = salt;
+ pd.IterationCount = iterations;
+
+ HMACSHA1 hmac = (HMACSHA1) HMACSHA1.Create ();
+ hmac.Key = pd.DeriveMAC (20);
+ return hmac.ComputeHash (data, 0, data.Length);
+ }
+
+ /*
+ * SafeContents ::= SEQUENCE OF SafeBag
+ *
+ * SafeBag ::= SEQUENCE {
+ * bagId BAG-TYPE.&id ({PKCS12BagSet}),
+ * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
+ * bagAttributes SET OF PKCS12Attribute OPTIONAL
+ * }
+ */
+ public byte[] GetBytes ()
+ {
+ // TODO (incomplete)
+ ASN1 safeBagSequence = new ASN1 (0x30);
+
+ // Sync Safe Bag list since X509CertificateCollection may be updated
+ ArrayList scs = new ArrayList ();
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (certBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS7.ContentInfo cert = new PKCS7.ContentInfo (bagValue.Value);
+ scs.Add (new X509Certificate (cert.Content [0].Value));
+ }
+ }
+
+ ArrayList addcerts = new ArrayList ();
+ ArrayList removecerts = new ArrayList ();
+
+ foreach (X509Certificate c in Certificates) {
+ bool found = false;
+
+ foreach (X509Certificate lc in scs) {
+ if (Compare (c.RawData, lc.RawData)) {
+ found = true;
+ }
+ }
+
+ if (!found) {
+ addcerts.Add (c);
+ }
+ }
+ foreach (X509Certificate c in scs) {
+ bool found = false;
+
+ foreach (X509Certificate lc in Certificates) {
+ if (Compare (c.RawData, lc.RawData)) {
+ found = true;
+ }
+ }
+
+ if (!found) {
+ removecerts.Add (c);
+ }
+ }
+
+ foreach (X509Certificate c in removecerts) {
+ RemoveCertificate (c);
+ }
+
+ foreach (X509Certificate c in addcerts) {
+ AddCertificate (c);
+ }
+ // Sync done
+
+ if (_safeBags.Count > 0) {
+ ASN1 certsSafeBag = new ASN1 (0x30);
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (certBag)) {
+ certsSafeBag.Add (sb.ASN1);
+ }
+ }
+
+ if (certsSafeBag.Count > 0) {
+ PKCS7.ContentInfo contentInfo = EncryptedContentInfo (certsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC);
+ safeBagSequence.Add (contentInfo.ASN1);
+ }
+ }
+
+ if (_safeBags.Count > 0) {
+ ASN1 safeContents = new ASN1 (0x30);
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (keyBag) ||
+ sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ safeContents.Add (sb.ASN1);
+ }
+ }
+ if (safeContents.Count > 0) {
+ ASN1 content = new ASN1 (0xA0);
+ content.Add (new ASN1 (0x04, safeContents.GetBytes ()));
+
+ PKCS7.ContentInfo keyBag = new PKCS7.ContentInfo (PKCS7.Oid.data);
+ keyBag.Content = content;
+ safeBagSequence.Add (keyBag.ASN1);
+ }
+ }
+
+ // Doing SecretBags separately in case we want to change their encryption independently.
+ if (_safeBags.Count > 0) {
+ ASN1 secretsSafeBag = new ASN1 (0x30);
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (secretBag)) {
+ secretsSafeBag.Add (sb.ASN1);
+ }
+ }
+
+ if (secretsSafeBag.Count > 0) {
+ PKCS7.ContentInfo contentInfo = EncryptedContentInfo (secretsSafeBag, pbeWithSHAAnd3KeyTripleDESCBC);
+ safeBagSequence.Add (contentInfo.ASN1);
+ }
+ }
+
+
+ ASN1 encapsulates = new ASN1 (0x04, safeBagSequence.GetBytes ());
+ ASN1 ci = new ASN1 (0xA0);
+ ci.Add (encapsulates);
+ PKCS7.ContentInfo authSafe = new PKCS7.ContentInfo (PKCS7.Oid.data);
+ authSafe.Content = ci;
+
+ ASN1 macData = new ASN1 (0x30);
+ if (_password != null) {
+ // only for password based encryption
+ byte[] salt = new byte [20];
+ RNG.GetBytes (salt);
+ byte[] macValue = MAC (_password, salt, _iterations, authSafe.Content [0].Value);
+ ASN1 oidSeq = new ASN1 (0x30);
+ oidSeq.Add (ASN1Convert.FromOid ("1.3.14.3.2.26")); // SHA1
+ oidSeq.Add (new ASN1 (0x05));
+
+ ASN1 mac = new ASN1 (0x30);
+ mac.Add (oidSeq);
+ mac.Add (new ASN1 (0x04, macValue));
+
+ macData.Add (mac);
+ macData.Add (new ASN1 (0x04, salt));
+ macData.Add (ASN1Convert.FromInt32 (_iterations));
+ }
+
+ ASN1 version = new ASN1 (0x02, new byte [1] { 0x03 });
+
+ ASN1 pfx = new ASN1 (0x30);
+ pfx.Add (version);
+ pfx.Add (authSafe.ASN1);
+ if (macData.Count > 0) {
+ // only for password based encryption
+ pfx.Add (macData);
+ }
+
+ return pfx.GetBytes ();
+ }
+
+ // Creates an encrypted PKCS#7 ContentInfo with safeBags as its SafeContents. Used in GetBytes(), above.
+ private PKCS7.ContentInfo EncryptedContentInfo(ASN1 safeBags, string algorithmOid)
+ {
+ byte[] salt = new byte [8];
+ RNG.GetBytes (salt);
+
+ ASN1 seqParams = new ASN1 (0x30);
+ seqParams.Add (new ASN1 (0x04, salt));
+ seqParams.Add (ASN1Convert.FromInt32 (_iterations));
+
+ ASN1 seqPbe = new ASN1 (0x30);
+ seqPbe.Add (ASN1Convert.FromOid (algorithmOid));
+ seqPbe.Add (seqParams);
+
+ byte[] encrypted = Encrypt (algorithmOid, salt, _iterations, safeBags.GetBytes ());
+ ASN1 encryptedContent = new ASN1 (0x80, encrypted);
+
+ ASN1 seq = new ASN1 (0x30);
+ seq.Add (ASN1Convert.FromOid (PKCS7.Oid.data));
+ seq.Add (seqPbe);
+ seq.Add (encryptedContent);
+
+ ASN1 version = new ASN1 (0x02, new byte [1] { 0x00 });
+ ASN1 encData = new ASN1 (0x30);
+ encData.Add (version);
+ encData.Add (seq);
+
+ ASN1 finalContent = new ASN1 (0xA0);
+ finalContent.Add (encData);
+
+ PKCS7.ContentInfo bag = new PKCS7.ContentInfo (PKCS7.Oid.encryptedData);
+ bag.Content = finalContent;
+ return bag;
+ }
+
+ public void AddCertificate (X509Certificate cert)
+ {
+ AddCertificate (cert, null);
+ }
+
+ public void AddCertificate (X509Certificate cert, IDictionary attributes)
+ {
+ bool found = false;
+
+ for (int i = 0; !found && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (certBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value);
+ X509Certificate c = new X509Certificate (crt.Content [0].Value);
+ if (Compare (cert.RawData, c.RawData)) {
+ found = true;
+ }
+ }
+ }
+
+ if (!found) {
+ _safeBags.Add (new SafeBag (certBag, CertificateSafeBag (cert, attributes)));
+ _certsChanged = true;
+ }
+ }
+
+ public void RemoveCertificate (X509Certificate cert)
+ {
+ RemoveCertificate (cert, null);
+ }
+
+ public void RemoveCertificate (X509Certificate cert, IDictionary attrs)
+ {
+ int certIndex = -1;
+
+ for (int i = 0; certIndex == -1 && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (certBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value);
+ X509Certificate c = new X509Certificate (crt.Content [0].Value);
+ if (Compare (cert.RawData, c.RawData)) {
+ if (attrs != null) {
+ if (safeBag.Count == 3) {
+ ASN1 bagAttributes = safeBag [2];
+ int bagAttributesFound = 0;
+ for (int j = 0; j < bagAttributes.Count; j++) {
+ ASN1 pkcs12Attribute = bagAttributes [j];
+ ASN1 attrId = pkcs12Attribute [0];
+ string ao = ASN1Convert.ToOid (attrId);
+ ArrayList dattrValues = (ArrayList)attrs [ao];
+
+ if (dattrValues != null) {
+ ASN1 attrValues = pkcs12Attribute [1];
+
+ if (dattrValues.Count == attrValues.Count) {
+ int attrValuesFound = 0;
+ for (int k = 0; k < attrValues.Count; k++) {
+ ASN1 attrValue = attrValues [k];
+ byte[] value = (byte[])dattrValues [k];
+
+ if (Compare (value, attrValue.Value)) {
+ attrValuesFound += 1;
+ }
+ }
+ if (attrValuesFound == attrValues.Count) {
+ bagAttributesFound += 1;
+ }
+ }
+ }
+ }
+ if (bagAttributesFound == bagAttributes.Count) {
+ certIndex = i;
+ }
+ }
+ } else {
+ certIndex = i;
+ }
+ }
+ }
+ }
+
+ if (certIndex != -1) {
+ _safeBags.RemoveAt (certIndex);
+ _certsChanged = true;
+ }
+ }
+
+ private bool CompareAsymmetricAlgorithm (AsymmetricAlgorithm a1, AsymmetricAlgorithm a2)
+ {
+ // fast path
+ if (a1.KeySize != a2.KeySize)
+ return false;
+ // compare public keys - if they match we can assume the private match too
+ return (a1.ToXmlString (false) == a2.ToXmlString (false));
+ }
+
+ public void AddPkcs8ShroudedKeyBag (AsymmetricAlgorithm aa)
+ {
+ AddPkcs8ShroudedKeyBag (aa, null);
+ }
+
+ public void AddPkcs8ShroudedKeyBag (AsymmetricAlgorithm aa, IDictionary attributes)
+ {
+ bool found = false;
+
+ for (int i = 0; !found && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ ASN1 bagValue = sb.ASN1 [1];
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
+ byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted);
+ byte[] privateKey = pki.PrivateKey;
+
+ AsymmetricAlgorithm saa = null;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ Array.Clear (decrypted, 0, decrypted.Length);
+ Array.Clear (privateKey, 0, privateKey.Length);
+ throw new CryptographicException ("Unknown private key format");
+ }
+
+ Array.Clear (decrypted, 0, decrypted.Length);
+ Array.Clear (privateKey, 0, privateKey.Length);
+
+ if (CompareAsymmetricAlgorithm (aa , saa)) {
+ found = true;
+ }
+ }
+ }
+
+ if (!found) {
+ _safeBags.Add (new SafeBag (pkcs8ShroudedKeyBag, Pkcs8ShroudedKeyBagSafeBag (aa, attributes)));
+ _keyBagsChanged = true;
+ }
+ }
+
+ public void RemovePkcs8ShroudedKeyBag (AsymmetricAlgorithm aa)
+ {
+ int aaIndex = -1;
+
+ for (int i = 0; aaIndex == -1 && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ ASN1 bagValue = sb.ASN1 [1];
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
+ byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted);
+ byte[] privateKey = pki.PrivateKey;
+
+ AsymmetricAlgorithm saa = null;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ Array.Clear (decrypted, 0, decrypted.Length);
+ Array.Clear (privateKey, 0, privateKey.Length);
+ throw new CryptographicException ("Unknown private key format");
+ }
+
+ Array.Clear (decrypted, 0, decrypted.Length);
+ Array.Clear (privateKey, 0, privateKey.Length);
+
+ if (CompareAsymmetricAlgorithm (aa, saa)) {
+ aaIndex = i;
+ }
+ }
+ }
+
+ if (aaIndex != -1) {
+ _safeBags.RemoveAt (aaIndex);
+ _keyBagsChanged = true;
+ }
+ }
+
+ public void AddKeyBag (AsymmetricAlgorithm aa)
+ {
+ AddKeyBag (aa, null);
+ }
+
+ public void AddKeyBag (AsymmetricAlgorithm aa, IDictionary attributes)
+ {
+ bool found = false;
+
+ for (int i = 0; !found && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (keyBag)) {
+ ASN1 bagValue = sb.ASN1 [1];
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value);
+ byte[] privateKey = pki.PrivateKey;
+
+ AsymmetricAlgorithm saa = null;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ Array.Clear (privateKey, 0, privateKey.Length);
+ throw new CryptographicException ("Unknown private key format");
+ }
+
+ Array.Clear (privateKey, 0, privateKey.Length);
+
+ if (CompareAsymmetricAlgorithm (aa, saa)) {
+ found = true;
+ }
+ }
+ }
+
+ if (!found) {
+ _safeBags.Add (new SafeBag (keyBag, KeyBagSafeBag (aa, attributes)));
+ _keyBagsChanged = true;
+ }
+ }
+
+ public void RemoveKeyBag (AsymmetricAlgorithm aa)
+ {
+ int aaIndex = -1;
+
+ for (int i = 0; aaIndex == -1 && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (keyBag)) {
+ ASN1 bagValue = sb.ASN1 [1];
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value);
+ byte[] privateKey = pki.PrivateKey;
+
+ AsymmetricAlgorithm saa = null;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ Array.Clear (privateKey, 0, privateKey.Length);
+ throw new CryptographicException ("Unknown private key format");
+ }
+
+ Array.Clear (privateKey, 0, privateKey.Length);
+
+ if (CompareAsymmetricAlgorithm (aa, saa)) {
+ aaIndex = i;
+ }
+ }
+ }
+
+ if (aaIndex != -1) {
+ _safeBags.RemoveAt (aaIndex);
+ _keyBagsChanged = true;
+ }
+ }
+
+ public void AddSecretBag (byte[] secret)
+ {
+ AddSecretBag (secret, null);
+ }
+
+ public void AddSecretBag (byte[] secret, IDictionary attributes)
+ {
+ bool found = false;
+
+ for (int i = 0; !found && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (secretBag)) {
+ ASN1 bagValue = sb.ASN1 [1];
+ byte[] ssecret = bagValue.Value;
+
+ if (Compare (secret, ssecret)) {
+ found = true;
+ }
+ }
+ }
+
+ if (!found) {
+ _safeBags.Add (new SafeBag (secretBag, SecretBagSafeBag (secret, attributes)));
+ _secretBagsChanged = true;
+ }
+ }
+
+ public void RemoveSecretBag (byte[] secret)
+ {
+ int sIndex = -1;
+
+ for (int i = 0; sIndex == -1 && i < _safeBags.Count; i++) {
+ SafeBag sb = (SafeBag)_safeBags [i];
+
+ if (sb.BagOID.Equals (secretBag)) {
+ ASN1 bagValue = sb.ASN1 [1];
+ byte[] ssecret = bagValue.Value;
+
+ if (Compare (secret, ssecret)) {
+ sIndex = i;
+ }
+ }
+ }
+
+ if (sIndex != -1) {
+ _safeBags.RemoveAt (sIndex);
+ _secretBagsChanged = true;
+ }
+ }
+
+ public AsymmetricAlgorithm GetAsymmetricAlgorithm (IDictionary attrs)
+ {
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ ASN1 safeBag = sb.ASN1;
+
+ if (safeBag.Count == 3) {
+ ASN1 bagAttributes = safeBag [2];
+
+ int bagAttributesFound = 0;
+ for (int i = 0; i < bagAttributes.Count; i++) {
+ ASN1 pkcs12Attribute = bagAttributes [i];
+ ASN1 attrId = pkcs12Attribute [0];
+ string ao = ASN1Convert.ToOid (attrId);
+ ArrayList dattrValues = (ArrayList)attrs [ao];
+
+ if (dattrValues != null) {
+ ASN1 attrValues = pkcs12Attribute [1];
+
+ if (dattrValues.Count == attrValues.Count) {
+ int attrValuesFound = 0;
+ for (int j = 0; j < attrValues.Count; j++) {
+ ASN1 attrValue = attrValues [j];
+ byte[] value = (byte[])dattrValues [j];
+
+ if (Compare (value, attrValue.Value)) {
+ attrValuesFound += 1;
+ }
+ }
+ if (attrValuesFound == attrValues.Count) {
+ bagAttributesFound += 1;
+ }
+ }
+ }
+ }
+ if (bagAttributesFound == bagAttributes.Count) {
+ ASN1 bagValue = safeBag [1];
+ AsymmetricAlgorithm aa = null;
+ if (sb.BagOID.Equals (keyBag)) {
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value);
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ aa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ aa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ break;
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+ } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
+ byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted);
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ aa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ aa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ break;
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+ Array.Clear (decrypted, 0, decrypted.Length);
+ }
+ return aa;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public byte[] GetSecret (IDictionary attrs)
+ {
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (secretBag)) {
+ ASN1 safeBag = sb.ASN1;
+
+ if (safeBag.Count == 3) {
+ ASN1 bagAttributes = safeBag [2];
+
+ int bagAttributesFound = 0;
+ for (int i = 0; i < bagAttributes.Count; i++) {
+ ASN1 pkcs12Attribute = bagAttributes [i];
+ ASN1 attrId = pkcs12Attribute [0];
+ string ao = ASN1Convert.ToOid (attrId);
+ ArrayList dattrValues = (ArrayList)attrs [ao];
+
+ if (dattrValues != null) {
+ ASN1 attrValues = pkcs12Attribute [1];
+
+ if (dattrValues.Count == attrValues.Count) {
+ int attrValuesFound = 0;
+ for (int j = 0; j < attrValues.Count; j++) {
+ ASN1 attrValue = attrValues [j];
+ byte[] value = (byte[])dattrValues [j];
+
+ if (Compare (value, attrValue.Value)) {
+ attrValuesFound += 1;
+ }
+ }
+ if (attrValuesFound == attrValues.Count) {
+ bagAttributesFound += 1;
+ }
+ }
+ }
+ }
+ if (bagAttributesFound == bagAttributes.Count) {
+ ASN1 bagValue = safeBag [1];
+ return bagValue.Value;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public X509Certificate GetCertificate (IDictionary attrs)
+ {
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (certBag)) {
+ ASN1 safeBag = sb.ASN1;
+
+ if (safeBag.Count == 3) {
+ ASN1 bagAttributes = safeBag [2];
+
+ int bagAttributesFound = 0;
+ for (int i = 0; i < bagAttributes.Count; i++) {
+ ASN1 pkcs12Attribute = bagAttributes [i];
+ ASN1 attrId = pkcs12Attribute [0];
+ string ao = ASN1Convert.ToOid (attrId);
+ ArrayList dattrValues = (ArrayList)attrs [ao];
+
+ if (dattrValues != null) {
+ ASN1 attrValues = pkcs12Attribute [1];
+
+ if (dattrValues.Count == attrValues.Count) {
+ int attrValuesFound = 0;
+ for (int j = 0; j < attrValues.Count; j++) {
+ ASN1 attrValue = attrValues [j];
+ byte[] value = (byte[])dattrValues [j];
+
+ if (Compare (value, attrValue.Value)) {
+ attrValuesFound += 1;
+ }
+ }
+ if (attrValuesFound == attrValues.Count) {
+ bagAttributesFound += 1;
+ }
+ }
+ }
+ }
+ if (bagAttributesFound == bagAttributes.Count) {
+ ASN1 bagValue = safeBag [1];
+ PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value);
+ return new X509Certificate (crt.Content [0].Value);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public IDictionary GetAttributes (AsymmetricAlgorithm aa)
+ {
+ IDictionary result = new Hashtable ();
+
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (keyBag) || sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ ASN1 safeBag = sb.ASN1;
+
+ ASN1 bagValue = safeBag [1];
+ AsymmetricAlgorithm saa = null;
+ if (sb.BagOID.Equals (keyBag)) {
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (bagValue.Value);
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ break;
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+ } else if (sb.BagOID.Equals (pkcs8ShroudedKeyBag)) {
+ PKCS8.EncryptedPrivateKeyInfo epki = new PKCS8.EncryptedPrivateKeyInfo (bagValue.Value);
+ byte[] decrypted = Decrypt (epki.Algorithm, epki.Salt, epki.IterationCount, epki.EncryptedData);
+ PKCS8.PrivateKeyInfo pki = new PKCS8.PrivateKeyInfo (decrypted);
+ byte[] privateKey = pki.PrivateKey;
+ switch (privateKey [0]) {
+ case 0x02:
+ DSAParameters p = new DSAParameters (); // FIXME
+ saa = PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p);
+ break;
+ case 0x30:
+ saa = PKCS8.PrivateKeyInfo.DecodeRSA (privateKey);
+ break;
+ default:
+ break;
+ }
+ Array.Clear (privateKey, 0, privateKey.Length);
+ Array.Clear (decrypted, 0, decrypted.Length);
+ }
+
+ if (saa != null && CompareAsymmetricAlgorithm (saa, aa)) {
+ if (safeBag.Count == 3) {
+ ASN1 bagAttributes = safeBag [2];
+
+ for (int i = 0; i < bagAttributes.Count; i++) {
+ ASN1 pkcs12Attribute = bagAttributes [i];
+ ASN1 attrId = pkcs12Attribute [0];
+ string aOid = ASN1Convert.ToOid (attrId);
+ ArrayList aValues = new ArrayList ();
+
+ ASN1 attrValues = pkcs12Attribute [1];
+
+ for (int j = 0; j < attrValues.Count; j++) {
+ ASN1 attrValue = attrValues [j];
+ aValues.Add (attrValue.Value);
+ }
+ result.Add (aOid, aValues);
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public IDictionary GetAttributes (X509Certificate cert)
+ {
+ IDictionary result = new Hashtable ();
+
+ foreach (SafeBag sb in _safeBags) {
+ if (sb.BagOID.Equals (certBag)) {
+ ASN1 safeBag = sb.ASN1;
+ ASN1 bagValue = safeBag [1];
+ PKCS7.ContentInfo crt = new PKCS7.ContentInfo (bagValue.Value);
+ X509Certificate xc = new X509Certificate (crt.Content [0].Value);
+
+ if (Compare (cert.RawData, xc.RawData)) {
+ if (safeBag.Count == 3) {
+ ASN1 bagAttributes = safeBag [2];
+
+ for (int i = 0; i < bagAttributes.Count; i++) {
+ ASN1 pkcs12Attribute = bagAttributes [i];
+ ASN1 attrId = pkcs12Attribute [0];
+
+ string aOid = ASN1Convert.ToOid (attrId);
+ ArrayList aValues = new ArrayList ();
+
+ ASN1 attrValues = pkcs12Attribute [1];
+
+ for (int j = 0; j < attrValues.Count; j++) {
+ ASN1 attrValue = attrValues [j];
+ aValues.Add (attrValue.Value);
+ }
+ result.Add (aOid, aValues);
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public void SaveToFile (string filename)
+ {
+ if (filename == null)
+ throw new ArgumentNullException ("filename");
+
+ using (FileStream fs = File.Create (filename)) {
+ byte[] data = GetBytes ();
+ fs.Write (data, 0, data.Length);
+ }
+ }
+
+ public object Clone ()
+ {
+ PKCS12 clone = null;
+ if (_password != null) {
+ clone = new PKCS12 (GetBytes (), Encoding.BigEndianUnicode.GetString (_password));
+ } else {
+ clone = new PKCS12 (GetBytes ());
+ }
+ clone.IterationCount = this.IterationCount;
+
+ return clone;
+ }
+
+ // static
+
+ public const int CryptoApiPasswordLimit = 32;
+
+ static private int password_max_length = Int32.MaxValue;
+
+ // static properties
+
+ // MS CryptoAPI limits the password to a maximum of 31 characters
+ // other implementations, like OpenSSL, have no such limitation.
+ // Setting a maximum value will truncate the password length to
+ // ensure compatibility with MS's PFXImportCertStore API.
+ static public int MaximumPasswordLength {
+ get { return password_max_length; }
+ set {
+ if (value < CryptoApiPasswordLimit) {
+ string msg = string.Format ("Maximum password length cannot be less than {0}.", CryptoApiPasswordLimit);
+ throw new ArgumentOutOfRangeException (msg);
+ }
+ password_max_length = value;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs
new file mode 100644
index 000000000..1b1a3295b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS7.cs
@@ -0,0 +1,1012 @@
+//
+// PKCS7.cs: PKCS #7 - Cryptographic Message Syntax Standard
+// http://www.rsasecurity.com/rsalabs/pkcs/pkcs-7/index.html
+//
+// Authors:
+// Sebastien Pouliot <sebastien@ximian.com>
+// Daniel Granath <dgranath#gmail.com>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ public sealed class PKCS7 {
+
+ public class Oid {
+ // pkcs 1
+ public const string rsaEncryption = "1.2.840.113549.1.1.1";
+ // pkcs 7
+ public const string data = "1.2.840.113549.1.7.1";
+ public const string signedData = "1.2.840.113549.1.7.2";
+ public const string envelopedData = "1.2.840.113549.1.7.3";
+ public const string signedAndEnvelopedData = "1.2.840.113549.1.7.4";
+ public const string digestedData = "1.2.840.113549.1.7.5";
+ public const string encryptedData = "1.2.840.113549.1.7.6";
+ // pkcs 9
+ public const string contentType = "1.2.840.113549.1.9.3";
+ public const string messageDigest = "1.2.840.113549.1.9.4";
+ public const string signingTime = "1.2.840.113549.1.9.5";
+ public const string countersignature = "1.2.840.113549.1.9.6";
+
+ public Oid ()
+ {
+ }
+ }
+
+ private PKCS7 ()
+ {
+ }
+
+ static public ASN1 Attribute (string oid, ASN1 value)
+ {
+ ASN1 attr = new ASN1 (0x30);
+ attr.Add (ASN1Convert.FromOid (oid));
+ ASN1 aset = attr.Add (new ASN1 (0x31));
+ aset.Add (value);
+ return attr;
+ }
+
+ static public ASN1 AlgorithmIdentifier (string oid)
+ {
+ ASN1 ai = new ASN1 (0x30);
+ ai.Add (ASN1Convert.FromOid (oid));
+ ai.Add (new ASN1 (0x05)); // NULL
+ return ai;
+ }
+
+ static public ASN1 AlgorithmIdentifier (string oid, ASN1 parameters)
+ {
+ ASN1 ai = new ASN1 (0x30);
+ ai.Add (ASN1Convert.FromOid (oid));
+ ai.Add (parameters);
+ return ai;
+ }
+
+ /*
+ * IssuerAndSerialNumber ::= SEQUENCE {
+ * issuer Name,
+ * serialNumber CertificateSerialNumber
+ * }
+ */
+ static public ASN1 IssuerAndSerialNumber (X509Certificate x509)
+ {
+ ASN1 issuer = null;
+ ASN1 serial = null;
+ ASN1 cert = new ASN1 (x509.RawData);
+ int tbs = 0;
+ bool flag = false;
+ while (tbs < cert[0].Count) {
+ ASN1 e = cert[0][tbs++];
+ if (e.Tag == 0x02)
+ serial = e;
+ else if (e.Tag == 0x30) {
+ if (flag) {
+ issuer = e;
+ break;
+ }
+ flag = true;
+ }
+ }
+ ASN1 iasn = new ASN1 (0x30);
+ iasn.Add (issuer);
+ iasn.Add (serial);
+ return iasn;
+ }
+
+ /*
+ * ContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
+ * }
+ * ContentType ::= OBJECT IDENTIFIER
+ */
+ public class ContentInfo {
+
+ private string contentType;
+ private ASN1 content;
+
+ public ContentInfo ()
+ {
+ content = new ASN1 (0xA0);
+ }
+
+ public ContentInfo (string oid) : this ()
+ {
+ contentType = oid;
+ }
+
+ public ContentInfo (byte[] data)
+ : this (new ASN1 (data)) {}
+
+ public ContentInfo (ASN1 asn1)
+ {
+ // SEQUENCE with 1 or 2 elements
+ if ((asn1.Tag != 0x30) || ((asn1.Count < 1) && (asn1.Count > 2)))
+ throw new ArgumentException ("Invalid ASN1");
+ if (asn1[0].Tag != 0x06)
+ throw new ArgumentException ("Invalid contentType");
+ contentType = ASN1Convert.ToOid (asn1[0]);
+ if (asn1.Count > 1) {
+ if (asn1[1].Tag != 0xA0)
+ throw new ArgumentException ("Invalid content");
+ content = asn1[1];
+ }
+ }
+
+ public ASN1 ASN1 {
+ get { return GetASN1(); }
+ }
+
+ public ASN1 Content {
+ get { return content; }
+ set { content = value; }
+ }
+
+ public string ContentType {
+ get { return contentType; }
+ set { contentType = value; }
+ }
+
+ internal ASN1 GetASN1 ()
+ {
+ // ContentInfo ::= SEQUENCE {
+ ASN1 contentInfo = new ASN1 (0x30);
+ // contentType ContentType, -> ContentType ::= OBJECT IDENTIFIER
+ contentInfo.Add (ASN1Convert.FromOid (contentType));
+ // content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
+ if ((content != null) && (content.Count > 0))
+ contentInfo.Add (content);
+ return contentInfo;
+ }
+
+ public byte[] GetBytes ()
+ {
+ return GetASN1 ().GetBytes ();
+ }
+ }
+
+ /*
+ * EncryptedData ::= SEQUENCE {
+ * version INTEGER {edVer0(0)} (edVer0),
+ * encryptedContentInfo EncryptedContentInfo
+ * }
+ */
+ public class EncryptedData {
+ private byte _version;
+ private ContentInfo _content;
+ private ContentInfo _encryptionAlgorithm;
+ private byte[] _encrypted;
+
+ public EncryptedData ()
+ {
+ _version = 0;
+ }
+
+ public EncryptedData (byte[] data)
+ : this (new ASN1 (data))
+ {
+ }
+
+ public EncryptedData (ASN1 asn1) : this ()
+ {
+ if ((asn1.Tag != 0x30) || (asn1.Count < 2))
+ throw new ArgumentException ("Invalid EncryptedData");
+
+ if (asn1 [0].Tag != 0x02)
+ throw new ArgumentException ("Invalid version");
+ _version = asn1 [0].Value [0];
+
+ ASN1 encryptedContentInfo = asn1 [1];
+ if (encryptedContentInfo.Tag != 0x30)
+ throw new ArgumentException ("missing EncryptedContentInfo");
+
+ ASN1 contentType = encryptedContentInfo [0];
+ if (contentType.Tag != 0x06)
+ throw new ArgumentException ("missing EncryptedContentInfo.ContentType");
+ _content = new ContentInfo (ASN1Convert.ToOid (contentType));
+
+ ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1];
+ if (contentEncryptionAlgorithm.Tag != 0x30)
+ throw new ArgumentException ("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier");
+ _encryptionAlgorithm = new ContentInfo (ASN1Convert.ToOid (contentEncryptionAlgorithm [0]));
+ _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1];
+
+ ASN1 encryptedContent = encryptedContentInfo [2];
+ if (encryptedContent.Tag != 0x80)
+ throw new ArgumentException ("missing EncryptedContentInfo.EncryptedContent");
+ _encrypted = encryptedContent.Value;
+ }
+
+ public ASN1 ASN1 {
+ get { return GetASN1(); }
+ }
+
+ public ContentInfo ContentInfo {
+ get { return _content; }
+ }
+
+ public ContentInfo EncryptionAlgorithm {
+ get { return _encryptionAlgorithm; }
+ }
+
+ public byte[] EncryptedContent {
+ get {
+ if (_encrypted == null)
+ return null;
+ return (byte[]) _encrypted.Clone ();
+ }
+ }
+
+ public byte Version {
+ get { return _version; }
+ set { _version = value; }
+ }
+
+ // methods
+
+ internal ASN1 GetASN1 ()
+ {
+ return null;
+ }
+
+ public byte[] GetBytes ()
+ {
+ return GetASN1 ().GetBytes ();
+ }
+ }
+
+ /*
+ * EnvelopedData ::= SEQUENCE {
+ * version Version,
+ * recipientInfos RecipientInfos,
+ * encryptedContentInfo EncryptedContentInfo
+ * }
+ *
+ * RecipientInfos ::= SET OF RecipientInfo
+ *
+ * EncryptedContentInfo ::= SEQUENCE {
+ * contentType ContentType,
+ * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+ * }
+ *
+ * EncryptedContent ::= OCTET STRING
+ *
+ */
+ public class EnvelopedData {
+ private byte _version;
+ private ContentInfo _content;
+ private ContentInfo _encryptionAlgorithm;
+ private ArrayList _recipientInfos;
+ private byte[] _encrypted;
+
+ public EnvelopedData ()
+ {
+ _version = 0;
+ _content = new ContentInfo ();
+ _encryptionAlgorithm = new ContentInfo ();
+ _recipientInfos = new ArrayList ();
+ }
+
+ public EnvelopedData (byte[] data)
+ : this (new ASN1 (data))
+ {
+ }
+
+ public EnvelopedData (ASN1 asn1) : this ()
+ {
+ if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 3))
+ throw new ArgumentException ("Invalid EnvelopedData");
+
+ if (asn1[0][0].Tag != 0x02)
+ throw new ArgumentException ("Invalid version");
+ _version = asn1[0][0].Value[0];
+
+ // recipientInfos
+
+ ASN1 recipientInfos = asn1 [0][1];
+ if (recipientInfos.Tag != 0x31)
+ throw new ArgumentException ("missing RecipientInfos");
+ for (int i=0; i < recipientInfos.Count; i++) {
+ ASN1 recipientInfo = recipientInfos [i];
+ _recipientInfos.Add (new RecipientInfo (recipientInfo));
+ }
+
+ ASN1 encryptedContentInfo = asn1[0][2];
+ if (encryptedContentInfo.Tag != 0x30)
+ throw new ArgumentException ("missing EncryptedContentInfo");
+
+ ASN1 contentType = encryptedContentInfo [0];
+ if (contentType.Tag != 0x06)
+ throw new ArgumentException ("missing EncryptedContentInfo.ContentType");
+ _content = new ContentInfo (ASN1Convert.ToOid (contentType));
+
+ ASN1 contentEncryptionAlgorithm = encryptedContentInfo [1];
+ if (contentEncryptionAlgorithm.Tag != 0x30)
+ throw new ArgumentException ("missing EncryptedContentInfo.ContentEncryptionAlgorithmIdentifier");
+ _encryptionAlgorithm = new ContentInfo (ASN1Convert.ToOid (contentEncryptionAlgorithm [0]));
+ _encryptionAlgorithm.Content = contentEncryptionAlgorithm [1];
+
+ ASN1 encryptedContent = encryptedContentInfo [2];
+ if (encryptedContent.Tag != 0x80)
+ throw new ArgumentException ("missing EncryptedContentInfo.EncryptedContent");
+ _encrypted = encryptedContent.Value;
+ }
+
+ public ArrayList RecipientInfos {
+ get { return _recipientInfos; }
+ }
+
+ public ASN1 ASN1 {
+ get { return GetASN1(); }
+ }
+
+ public ContentInfo ContentInfo {
+ get { return _content; }
+ }
+
+ public ContentInfo EncryptionAlgorithm {
+ get { return _encryptionAlgorithm; }
+ }
+
+ public byte[] EncryptedContent {
+ get {
+ if (_encrypted == null)
+ return null;
+ return (byte[]) _encrypted.Clone ();
+ }
+ }
+
+ public byte Version {
+ get { return _version; }
+ set { _version = value; }
+ }
+
+ internal ASN1 GetASN1 ()
+ {
+ // SignedData ::= SEQUENCE {
+ ASN1 signedData = new ASN1 (0x30);
+ // version Version -> Version ::= INTEGER
+/* byte[] ver = { _version };
+ signedData.Add (new ASN1 (0x02, ver));
+ // digestAlgorithms DigestAlgorithmIdentifiers -> DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+ ASN1 digestAlgorithms = signedData.Add (new ASN1 (0x31));
+ if (hashAlgorithm != null) {
+ string hashOid = CryptoConfig.MapNameToOid (hashAlgorithm);
+ digestAlgorithms.Add (AlgorithmIdentifier (hashOid));
+ }
+
+ // contentInfo ContentInfo,
+ ASN1 ci = contentInfo.ASN1;
+ signedData.Add (ci);
+ if ((mda == null) && (hashAlgorithm != null)) {
+ // automatically add the messageDigest authenticated attribute
+ HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm);
+ byte[] idcHash = ha.ComputeHash (ci[1][0].Value);
+ ASN1 md = new ASN1 (0x30);
+ mda = Attribute (messageDigest, md.Add (new ASN1 (0x04, idcHash)));
+ signerInfo.AuthenticatedAttributes.Add (mda);
+ }
+
+ // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
+ if (certs.Count > 0) {
+ ASN1 a0 = signedData.Add (new ASN1 (0xA0));
+ foreach (X509Certificate x in certs)
+ a0.Add (new ASN1 (x.RawData));
+ }
+ // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ if (crls.Count > 0) {
+ ASN1 a1 = signedData.Add (new ASN1 (0xA1));
+ foreach (byte[] crl in crls)
+ a1.Add (new ASN1 (crl));
+ }
+ // signerInfos SignerInfos -> SignerInfos ::= SET OF SignerInfo
+ ASN1 signerInfos = signedData.Add (new ASN1 (0x31));
+ if (signerInfo.Key != null)
+ signerInfos.Add (signerInfo.ASN1);*/
+ return signedData;
+ }
+
+ public byte[] GetBytes () {
+ return GetASN1 ().GetBytes ();
+ }
+ }
+
+ /* RecipientInfo ::= SEQUENCE {
+ * version Version,
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+ * encryptedKey EncryptedKey
+ * }
+ *
+ * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * EncryptedKey ::= OCTET STRING
+ */
+ public class RecipientInfo {
+
+ private int _version;
+ private string _oid;
+ private byte[] _key;
+ private byte[] _ski;
+ private string _issuer;
+ private byte[] _serial;
+
+ public RecipientInfo () {}
+
+ public RecipientInfo (ASN1 data)
+ {
+ if (data.Tag != 0x30)
+ throw new ArgumentException ("Invalid RecipientInfo");
+
+ ASN1 version = data [0];
+ if (version.Tag != 0x02)
+ throw new ArgumentException ("missing Version");
+ _version = version.Value [0];
+
+ // issuerAndSerialNumber IssuerAndSerialNumber
+ ASN1 subjectIdentifierType = data [1];
+ if ((subjectIdentifierType.Tag == 0x80) && (_version == 3)) {
+ _ski = subjectIdentifierType.Value;
+ }
+ else {
+ _issuer = X501.ToString (subjectIdentifierType [0]);
+ _serial = subjectIdentifierType [1].Value;
+ }
+
+ ASN1 keyEncryptionAlgorithm = data [2];
+ _oid = ASN1Convert.ToOid (keyEncryptionAlgorithm [0]);
+
+ ASN1 encryptedKey = data [3];
+ _key = encryptedKey.Value;
+ }
+
+ public string Oid {
+ get { return _oid; }
+ }
+
+ public byte[] Key {
+ get {
+ if (_key == null)
+ return null;
+ return (byte[]) _key.Clone ();
+ }
+ }
+
+ public byte[] SubjectKeyIdentifier {
+ get {
+ if (_ski == null)
+ return null;
+ return (byte[]) _ski.Clone ();
+ }
+ }
+
+ public string Issuer {
+ get { return _issuer; }
+ }
+
+ public byte[] Serial {
+ get {
+ if (_serial == null)
+ return null;
+ return (byte[]) _serial.Clone ();
+ }
+ }
+
+ public int Version {
+ get { return _version; }
+ }
+ }
+
+ /*
+ * SignedData ::= SEQUENCE {
+ * version Version,
+ * digestAlgorithms DigestAlgorithmIdentifiers,
+ * contentInfo ContentInfo,
+ * certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
+ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ * signerInfos SignerInfos
+ * }
+ */
+ public class SignedData {
+ private byte version;
+ private string hashAlgorithm;
+ private ContentInfo contentInfo;
+ private X509CertificateCollection certs;
+ private ArrayList crls;
+ private SignerInfo signerInfo;
+ private bool mda;
+ private bool signed;
+
+ public SignedData ()
+ {
+ version = 1;
+ contentInfo = new ContentInfo ();
+ certs = new X509CertificateCollection ();
+ crls = new ArrayList ();
+ signerInfo = new SignerInfo ();
+ mda = true;
+ signed = false;
+ }
+
+ public SignedData (byte[] data)
+ : this (new ASN1 (data))
+ {
+ }
+
+ public SignedData (ASN1 asn1)
+ {
+ if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 4))
+ throw new ArgumentException ("Invalid SignedData");
+
+ if (asn1[0][0].Tag != 0x02)
+ throw new ArgumentException ("Invalid version");
+ version = asn1[0][0].Value[0];
+
+ contentInfo = new ContentInfo (asn1[0][2]);
+
+ int n = 3;
+ certs = new X509CertificateCollection ();
+ if (asn1[0][n].Tag == 0xA0) {
+ for (int i=0; i < asn1[0][n].Count; i++)
+ certs.Add (new X509Certificate (asn1[0][n][i].GetBytes ()));
+ n++;
+ }
+
+ crls = new ArrayList ();
+ if (asn1[0][n].Tag == 0xA1) {
+ for (int i=0; i < asn1[0][n].Count; i++)
+ crls.Add (asn1[0][n][i].GetBytes ());
+ n++;
+ }
+
+ if (asn1[0][n].Count > 0)
+ signerInfo = new SignerInfo (asn1[0][n]);
+ else
+ signerInfo = new SignerInfo ();
+
+ // Exchange hash algorithm Oid from SignerInfo
+ if (signerInfo.HashName != null) {
+ HashName = OidToName(signerInfo.HashName);
+ }
+
+ // Check if SignerInfo has authenticated attributes
+ mda = (signerInfo.AuthenticatedAttributes.Count > 0);
+ }
+
+ public ASN1 ASN1 {
+ get { return GetASN1(); }
+ }
+
+ public X509CertificateCollection Certificates {
+ get { return certs; }
+ }
+
+ public ContentInfo ContentInfo {
+ get { return contentInfo; }
+ }
+
+ public ArrayList Crls {
+ get { return crls; }
+ }
+
+ public string HashName {
+ get { return hashAlgorithm; }
+ // todo add validation
+ set {
+ hashAlgorithm = value;
+ signerInfo.HashName = value;
+ }
+ }
+
+ public SignerInfo SignerInfo {
+ get { return signerInfo; }
+ }
+
+ public byte Version {
+ get { return version; }
+ set { version = value; }
+ }
+
+ public bool UseAuthenticatedAttributes {
+ get { return mda; }
+ set { mda = value; }
+ }
+
+ public bool VerifySignature (AsymmetricAlgorithm aa)
+ {
+ if (aa == null) {
+ return false;
+ }
+
+ RSAPKCS1SignatureDeformatter r = new RSAPKCS1SignatureDeformatter (aa);
+ r.SetHashAlgorithm (hashAlgorithm);
+ HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm);
+
+ byte[] signature = signerInfo.Signature;
+ byte[] hash = null;
+
+ if (mda) {
+ ASN1 asn = new ASN1 (0x31);
+ foreach (ASN1 attr in signerInfo.AuthenticatedAttributes)
+ asn.Add (attr);
+
+ hash = ha.ComputeHash (asn.GetBytes ());
+ } else {
+ hash = ha.ComputeHash (contentInfo.Content[0].Value);
+ }
+
+ if (hash != null && signature != null) {
+ return r.VerifySignature (hash, signature);
+ }
+ return false;
+ }
+
+ internal string OidToName (string oid)
+ {
+ switch (oid) {
+ case "1.3.14.3.2.26" :
+ return "SHA1";
+ case "1.2.840.113549.2.2" :
+ return "MD2";
+ case "1.2.840.113549.2.5" :
+ return "MD5";
+ case "2.16.840.1.101.3.4.1" :
+ return "SHA256";
+ case "2.16.840.1.101.3.4.2" :
+ return "SHA384";
+ case "2.16.840.1.101.3.4.3" :
+ return "SHA512";
+ default :
+ break;
+ }
+ // Unknown Oid
+ return oid;
+ }
+
+ internal ASN1 GetASN1 ()
+ {
+ // SignedData ::= SEQUENCE {
+ ASN1 signedData = new ASN1 (0x30);
+ // version Version -> Version ::= INTEGER
+ byte[] ver = { version };
+ signedData.Add (new ASN1 (0x02, ver));
+ // digestAlgorithms DigestAlgorithmIdentifiers -> DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+ ASN1 digestAlgorithms = signedData.Add (new ASN1 (0x31));
+ if (hashAlgorithm != null) {
+ string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm);
+ digestAlgorithms.Add (AlgorithmIdentifier (hashOid));
+ }
+
+ // contentInfo ContentInfo,
+ ASN1 ci = contentInfo.ASN1;
+ signedData.Add (ci);
+ if (!signed && (hashAlgorithm != null)) {
+ if (mda) {
+ // Use authenticated attributes for signature
+
+ // Automatically add the contentType authenticated attribute
+ ASN1 ctattr = Attribute (Oid.contentType, ci[0]);
+ signerInfo.AuthenticatedAttributes.Add (ctattr);
+
+ // Automatically add the messageDigest authenticated attribute
+ HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm);
+ byte[] idcHash = ha.ComputeHash (ci[1][0].Value);
+ ASN1 md = new ASN1 (0x30);
+ ASN1 mdattr = Attribute (Oid.messageDigest, md.Add (new ASN1 (0x04, idcHash)));
+ signerInfo.AuthenticatedAttributes.Add (mdattr);
+ } else {
+ // Don't use authenticated attributes for signature -- signature is content
+ RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (signerInfo.Key);
+ r.SetHashAlgorithm (hashAlgorithm);
+ HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm);
+ byte[] sig = ha.ComputeHash (ci[1][0].Value);
+ signerInfo.Signature = r.CreateSignature (sig);
+ }
+ signed = true;
+ }
+
+ // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
+ if (certs.Count > 0) {
+ ASN1 a0 = signedData.Add (new ASN1 (0xA0));
+ foreach (X509Certificate x in certs)
+ a0.Add (new ASN1 (x.RawData));
+ }
+ // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
+ if (crls.Count > 0) {
+ ASN1 a1 = signedData.Add (new ASN1 (0xA1));
+ foreach (byte[] crl in crls)
+ a1.Add (new ASN1 (crl));
+ }
+ // signerInfos SignerInfos -> SignerInfos ::= SET OF SignerInfo
+ ASN1 signerInfos = signedData.Add (new ASN1 (0x31));
+ if (signerInfo.Key != null)
+ signerInfos.Add (signerInfo.ASN1);
+ return signedData;
+ }
+
+ public byte[] GetBytes ()
+ {
+ return GetASN1 ().GetBytes ();
+ }
+ }
+
+ /*
+ * SignerInfo ::= SEQUENCE {
+ * version Version,
+ * issuerAndSerialNumber IssuerAndSerialNumber,
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+ * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ * encryptedDigest EncryptedDigest,
+ * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+ * }
+ *
+ * For version == 3 issuerAndSerialNumber may be replaced by ...
+ */
+ public class SignerInfo {
+
+ private byte version;
+ private X509Certificate x509;
+ private string hashAlgorithm;
+ private AsymmetricAlgorithm key;
+ private ArrayList authenticatedAttributes;
+ private ArrayList unauthenticatedAttributes;
+ private byte[] signature;
+ private string issuer;
+ private byte[] serial;
+ private byte[] ski;
+
+ public SignerInfo ()
+ {
+ version = 1;
+ authenticatedAttributes = new ArrayList ();
+ unauthenticatedAttributes = new ArrayList ();
+ }
+
+ public SignerInfo (byte[] data)
+ : this (new ASN1 (data)) {}
+
+ // TODO: INCOMPLETE
+ public SignerInfo (ASN1 asn1) : this ()
+ {
+ if ((asn1[0].Tag != 0x30) || (asn1[0].Count < 5))
+ throw new ArgumentException ("Invalid SignedData");
+
+ // version Version
+ if (asn1[0][0].Tag != 0x02)
+ throw new ArgumentException ("Invalid version");
+ version = asn1[0][0].Value[0];
+
+ // issuerAndSerialNumber IssuerAndSerialNumber
+ ASN1 subjectIdentifierType = asn1 [0][1];
+ if ((subjectIdentifierType.Tag == 0x80) && (version == 3)) {
+ ski = subjectIdentifierType.Value;
+ }
+ else {
+ issuer = X501.ToString (subjectIdentifierType [0]);
+ serial = subjectIdentifierType [1].Value;
+ }
+
+ // digestAlgorithm DigestAlgorithmIdentifier
+ ASN1 digestAlgorithm = asn1 [0][2];
+ hashAlgorithm = ASN1Convert.ToOid (digestAlgorithm [0]);
+
+ // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL
+ int n = 3;
+ ASN1 authAttributes = asn1 [0][n];
+ if (authAttributes.Tag == 0xA0) {
+ n++;
+ for (int i=0; i < authAttributes.Count; i++)
+ authenticatedAttributes.Add (authAttributes [i]);
+ }
+
+ // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier
+ n++;
+ // ASN1 digestEncryptionAlgorithm = asn1 [0][n++];
+ // string digestEncryptionAlgorithmOid = ASN1Convert.ToOid (digestEncryptionAlgorithm [0]);
+
+ // encryptedDigest EncryptedDigest
+ ASN1 encryptedDigest = asn1 [0][n++];
+ if (encryptedDigest.Tag == 0x04)
+ signature = encryptedDigest.Value;
+
+ // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+ ASN1 unauthAttributes = asn1 [0][n];
+ if ((unauthAttributes != null) && (unauthAttributes.Tag == 0xA1)) {
+ for (int i=0; i < unauthAttributes.Count; i++)
+ unauthenticatedAttributes.Add (unauthAttributes [i]);
+ }
+ }
+
+ public string IssuerName {
+ get { return issuer; }
+ }
+
+ public byte[] SerialNumber {
+ get {
+ if (serial == null)
+ return null;
+ return (byte[]) serial.Clone ();
+ }
+ }
+
+ public byte[] SubjectKeyIdentifier {
+ get {
+ if (ski == null)
+ return null;
+ return (byte[]) ski.Clone ();
+ }
+ }
+
+ public ASN1 ASN1 {
+ get { return GetASN1(); }
+ }
+
+ public ArrayList AuthenticatedAttributes {
+ get { return authenticatedAttributes; }
+ }
+
+ public X509Certificate Certificate {
+ get { return x509; }
+ set { x509 = value; }
+ }
+
+ public string HashName {
+ get { return hashAlgorithm; }
+ set { hashAlgorithm = value; }
+ }
+
+ public AsymmetricAlgorithm Key {
+ get { return key; }
+ set { key = value; }
+ }
+
+ public byte[] Signature {
+ get {
+ if (signature == null)
+ return null;
+ return (byte[]) signature.Clone ();
+ }
+
+ set {
+ if (value != null) {
+ signature = (byte[]) value.Clone ();
+ }
+ }
+ }
+
+ public ArrayList UnauthenticatedAttributes {
+ get { return unauthenticatedAttributes; }
+ }
+
+ public byte Version {
+ get { return version; }
+ set { version = value; }
+ }
+
+ internal ASN1 GetASN1 ()
+ {
+ if ((key == null) || (hashAlgorithm == null))
+ return null;
+ byte[] ver = { version };
+ ASN1 signerInfo = new ASN1 (0x30);
+ // version Version -> Version ::= INTEGER
+ signerInfo.Add (new ASN1 (0x02, ver));
+ // issuerAndSerialNumber IssuerAndSerialNumber,
+ signerInfo.Add (PKCS7.IssuerAndSerialNumber (x509));
+ // digestAlgorithm DigestAlgorithmIdentifier,
+ string hashOid = CryptoConfig.MapNameToOID (hashAlgorithm);
+ signerInfo.Add (AlgorithmIdentifier (hashOid));
+ // authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+ ASN1 aa = null;
+ if (authenticatedAttributes.Count > 0) {
+ aa = signerInfo.Add (new ASN1 (0xA0));
+ authenticatedAttributes.Sort(new SortedSet ());
+ foreach (ASN1 attr in authenticatedAttributes)
+ aa.Add (attr);
+ }
+ // digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+ if (key is RSA) {
+ signerInfo.Add (AlgorithmIdentifier (PKCS7.Oid.rsaEncryption));
+
+ if (aa != null) {
+ // Calculate the signature here; otherwise it must be set from SignedData
+ RSAPKCS1SignatureFormatter r = new RSAPKCS1SignatureFormatter (key);
+ r.SetHashAlgorithm (hashAlgorithm);
+ byte[] tbs = aa.GetBytes ();
+ tbs [0] = 0x31; // not 0xA0 for signature
+ HashAlgorithm ha = HashAlgorithm.Create (hashAlgorithm);
+ byte[] tbsHash = ha.ComputeHash (tbs);
+ signature = r.CreateSignature (tbsHash);
+ }
+ }
+ else if (key is DSA) {
+ throw new NotImplementedException ("not yet");
+ }
+ else
+ throw new CryptographicException ("Unknown assymetric algorithm");
+ // encryptedDigest EncryptedDigest,
+ signerInfo.Add (new ASN1 (0x04, signature));
+ // unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+ if (unauthenticatedAttributes.Count > 0) {
+ ASN1 ua = signerInfo.Add (new ASN1 (0xA1));
+ unauthenticatedAttributes.Sort(new SortedSet ());
+ foreach (ASN1 attr in unauthenticatedAttributes)
+ ua.Add (attr);
+ }
+ return signerInfo;
+ }
+
+ public byte[] GetBytes ()
+ {
+ return GetASN1 ().GetBytes ();
+ }
+ }
+
+ internal class SortedSet : IComparer {
+
+ public int Compare (object x, object y)
+ {
+ if (x == null)
+ return (y == null) ? 0 : -1;
+ else if (y == null)
+ return 1;
+
+ ASN1 xx = x as ASN1;
+ ASN1 yy = y as ASN1;
+
+ if ((xx == null) || (yy == null)) {
+ throw new ArgumentException (("Invalid objects."));
+ }
+
+ byte[] xb = xx.GetBytes ();
+ byte[] yb = yy.GetBytes ();
+
+ for (int i = 0; i < xb.Length; i++) {
+ if (i == yb.Length)
+ break;
+
+ if (xb[i] == yb[i])
+ continue;
+
+ return (xb[i] < yb[i]) ? -1 : 1;
+ }
+
+ // The arrays are equal up to the shortest of them.
+ if (xb.Length > yb.Length)
+ return 1;
+ else if (xb.Length < yb.Length)
+ return -1;
+
+ return 0;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs
new file mode 100644
index 000000000..b58ebdaf9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PKCS8.cs
@@ -0,0 +1,495 @@
+//
+// PKCS8.cs: PKCS #8 - Private-Key Information Syntax Standard
+// ftp://ftp.rsasecurity.com/pub/pkcs/doc/pkcs-8.doc
+//
+// Author:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com)
+// Copyright 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ public sealed class PKCS8 {
+
+ public enum KeyInfo {
+ PrivateKey,
+ EncryptedPrivateKey,
+ Unknown
+ }
+
+ private PKCS8 ()
+ {
+ }
+
+ static public KeyInfo GetType (byte[] data)
+ {
+ if (data == null)
+ throw new ArgumentNullException ("data");
+
+ KeyInfo ki = KeyInfo.Unknown;
+ try {
+ ASN1 top = new ASN1 (data);
+ if ((top.Tag == 0x30) && (top.Count > 0)) {
+ ASN1 firstLevel = top [0];
+ switch (firstLevel.Tag) {
+ case 0x02:
+ ki = KeyInfo.PrivateKey;
+ break;
+ case 0x30:
+ ki = KeyInfo.EncryptedPrivateKey;
+ break;
+ }
+ }
+ }
+ catch {
+ throw new CryptographicException ("invalid ASN.1 data");
+ }
+ return ki;
+ }
+
+ /*
+ * PrivateKeyInfo ::= SEQUENCE {
+ * version Version,
+ * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ * privateKey PrivateKey,
+ * attributes [0] IMPLICIT Attributes OPTIONAL
+ * }
+ *
+ * Version ::= INTEGER
+ *
+ * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * PrivateKey ::= OCTET STRING
+ *
+ * Attributes ::= SET OF Attribute
+ */
+ public class PrivateKeyInfo {
+
+ private int _version;
+ private string _algorithm;
+ private byte[] _key;
+ private ArrayList _list;
+
+ public PrivateKeyInfo ()
+ {
+ _version = 0;
+ _list = new ArrayList ();
+ }
+
+ public PrivateKeyInfo (byte[] data) : this ()
+ {
+ Decode (data);
+ }
+
+ // properties
+
+ public string Algorithm {
+ get { return _algorithm; }
+ set { _algorithm = value; }
+ }
+
+ public ArrayList Attributes {
+ get { return _list; }
+ }
+
+ public byte[] PrivateKey {
+ get {
+ if (_key == null)
+ return null;
+ return (byte[]) _key.Clone ();
+ }
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("PrivateKey");
+ _key = (byte[]) value.Clone ();
+ }
+ }
+
+ public int Version {
+ get { return _version; }
+ set {
+ if (value < 0)
+ throw new ArgumentOutOfRangeException ("negative version");
+ _version = value;
+ }
+ }
+
+ // methods
+
+ private void Decode (byte[] data)
+ {
+ ASN1 privateKeyInfo = new ASN1 (data);
+ if (privateKeyInfo.Tag != 0x30)
+ throw new CryptographicException ("invalid PrivateKeyInfo");
+
+ ASN1 version = privateKeyInfo [0];
+ if (version.Tag != 0x02)
+ throw new CryptographicException ("invalid version");
+ _version = version.Value [0];
+
+ ASN1 privateKeyAlgorithm = privateKeyInfo [1];
+ if (privateKeyAlgorithm.Tag != 0x30)
+ throw new CryptographicException ("invalid algorithm");
+
+ ASN1 algorithm = privateKeyAlgorithm [0];
+ if (algorithm.Tag != 0x06)
+ throw new CryptographicException ("missing algorithm OID");
+ _algorithm = ASN1Convert.ToOid (algorithm);
+
+ ASN1 privateKey = privateKeyInfo [2];
+ _key = privateKey.Value;
+
+ // attributes [0] IMPLICIT Attributes OPTIONAL
+ if (privateKeyInfo.Count > 3) {
+ ASN1 attributes = privateKeyInfo [3];
+ for (int i=0; i < attributes.Count; i++) {
+ _list.Add (attributes [i]);
+ }
+ }
+ }
+
+ public byte[] GetBytes ()
+ {
+ ASN1 privateKeyAlgorithm = new ASN1 (0x30);
+ privateKeyAlgorithm.Add (ASN1Convert.FromOid (_algorithm));
+ privateKeyAlgorithm.Add (new ASN1 (0x05)); // ASN.1 NULL
+
+ ASN1 pki = new ASN1 (0x30);
+ pki.Add (new ASN1 (0x02, new byte [1] { (byte) _version }));
+ pki.Add (privateKeyAlgorithm);
+ pki.Add (new ASN1 (0x04, _key));
+
+ if (_list.Count > 0) {
+ ASN1 attributes = new ASN1 (0xA0);
+ foreach (ASN1 attribute in _list) {
+ attributes.Add (attribute);
+ }
+ pki.Add (attributes);
+ }
+
+ return pki.GetBytes ();
+ }
+
+ // static methods
+
+ static private byte[] RemoveLeadingZero (byte[] bigInt)
+ {
+ int start = 0;
+ int length = bigInt.Length;
+ if (bigInt [0] == 0x00) {
+ start = 1;
+ length--;
+ }
+ byte[] bi = new byte [length];
+ Buffer.BlockCopy (bigInt, start, bi, 0, length);
+ return bi;
+ }
+
+ static private byte[] Normalize (byte[] bigInt, int length)
+ {
+ if (bigInt.Length == length)
+ return bigInt;
+ else if (bigInt.Length > length)
+ return RemoveLeadingZero (bigInt);
+ else {
+ // pad with 0
+ byte[] bi = new byte [length];
+ Buffer.BlockCopy (bigInt, 0, bi, (length - bigInt.Length), bigInt.Length);
+ return bi;
+ }
+ }
+
+ /*
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version,
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL
+ * }
+ */
+ static public RSA DecodeRSA (byte[] keypair)
+ {
+ ASN1 privateKey = new ASN1 (keypair);
+ if (privateKey.Tag != 0x30)
+ throw new CryptographicException ("invalid private key format");
+
+ ASN1 version = privateKey [0];
+ if (version.Tag != 0x02)
+ throw new CryptographicException ("missing version");
+
+ if (privateKey.Count < 9)
+ throw new CryptographicException ("not enough key parameters");
+
+ RSAParameters param = new RSAParameters ();
+ // note: MUST remove leading 0 - else MS wont import the key
+ param.Modulus = RemoveLeadingZero (privateKey [1].Value);
+ int keysize = param.Modulus.Length;
+ int keysize2 = (keysize >> 1); // half-size
+ // size must be normalized - else MS wont import the key
+ param.D = Normalize (privateKey [3].Value, keysize);
+ param.DP = Normalize (privateKey [6].Value, keysize2);
+ param.DQ = Normalize (privateKey [7].Value, keysize2);
+ param.Exponent = RemoveLeadingZero (privateKey [2].Value);
+ param.InverseQ = Normalize (privateKey [8].Value, keysize2);
+ param.P = Normalize (privateKey [4].Value, keysize2);
+ param.Q = Normalize (privateKey [5].Value, keysize2);
+
+ RSA rsa = null;
+ try {
+ rsa = RSA.Create ();
+ rsa.ImportParameters (param);
+ }
+ catch (CryptographicException) {
+ // this may cause problem when this code is run under
+ // the SYSTEM identity on Windows (e.g. ASP.NET). See
+ // http://bugzilla.ximian.com/show_bug.cgi?id=77559
+ CspParameters csp = new CspParameters();
+ csp.Flags = CspProviderFlags.UseMachineKeyStore;
+ rsa = new RSACryptoServiceProvider(csp);
+ rsa.ImportParameters(param);
+ }
+ return rsa;
+ }
+
+ /*
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version,
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL
+ * }
+ */
+ static public byte[] Encode (RSA rsa)
+ {
+ RSAParameters param = rsa.ExportParameters (true);
+
+ ASN1 rsaPrivateKey = new ASN1 (0x30);
+ rsaPrivateKey.Add (new ASN1 (0x02, new byte [1] { 0x00 }));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Modulus));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Exponent));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.D));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.P));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.Q));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DP));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.DQ));
+ rsaPrivateKey.Add (ASN1Convert.FromUnsignedBigInteger (param.InverseQ));
+
+ return rsaPrivateKey.GetBytes ();
+ }
+
+ // DSA only encode it's X private key inside an ASN.1 INTEGER (Hint: Tag == 0x02)
+ // which isn't enough for rebuilding the keypair. The other parameters
+ // can be found (98% of the time) in the X.509 certificate associated
+ // with the private key or (2% of the time) the parameters are in it's
+ // issuer X.509 certificate (not supported in the .NET framework).
+ static public DSA DecodeDSA (byte[] privateKey, DSAParameters dsaParameters)
+ {
+ ASN1 pvk = new ASN1 (privateKey);
+ if (pvk.Tag != 0x02)
+ throw new CryptographicException ("invalid private key format");
+
+ // X is ALWAYS 20 bytes (no matter if the key length is 512 or 1024 bits)
+ dsaParameters.X = Normalize (pvk.Value, 20);
+ DSA dsa = DSA.Create ();
+ dsa.ImportParameters (dsaParameters);
+ return dsa;
+ }
+
+ static public byte[] Encode (DSA dsa)
+ {
+ DSAParameters param = dsa.ExportParameters (true);
+ return ASN1Convert.FromUnsignedBigInteger (param.X).GetBytes ();
+ }
+
+ static public byte[] Encode (AsymmetricAlgorithm aa)
+ {
+ if (aa is RSA)
+ return Encode ((RSA)aa);
+ else if (aa is DSA)
+ return Encode ((DSA)aa);
+ else
+ throw new CryptographicException ("Unknown asymmetric algorithm {0}", aa.ToString ());
+ }
+ }
+
+ /*
+ * EncryptedPrivateKeyInfo ::= SEQUENCE {
+ * encryptionAlgorithm EncryptionAlgorithmIdentifier,
+ * encryptedData EncryptedData
+ * }
+ *
+ * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * EncryptedData ::= OCTET STRING
+ *
+ * --
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * -- from PKCS#5
+ * PBEParameter ::= SEQUENCE {
+ * salt OCTET STRING SIZE(8),
+ * iterationCount INTEGER
+ * }
+ */
+ public class EncryptedPrivateKeyInfo {
+
+ private string _algorithm;
+ private byte[] _salt;
+ private int _iterations;
+ private byte[] _data;
+
+ public EncryptedPrivateKeyInfo () {}
+
+ public EncryptedPrivateKeyInfo (byte[] data) : this ()
+ {
+ Decode (data);
+ }
+
+ // properties
+
+ public string Algorithm {
+ get { return _algorithm; }
+ set { _algorithm = value; }
+ }
+
+ public byte[] EncryptedData {
+ get { return (_data == null) ? null : (byte[]) _data.Clone (); }
+ set { _data = (value == null) ? null : (byte[]) value.Clone (); }
+ }
+
+ public byte[] Salt {
+ get {
+ if (_salt == null) {
+ RandomNumberGenerator rng = RandomNumberGenerator.Create ();
+ _salt = new byte [8];
+ rng.GetBytes (_salt);
+ }
+ return (byte[]) _salt.Clone ();
+ }
+ set { _salt = (byte[]) value.Clone (); }
+ }
+
+ public int IterationCount {
+ get { return _iterations; }
+ set {
+ if (value < 0)
+ throw new ArgumentOutOfRangeException ("IterationCount", "Negative");
+ _iterations = value;
+ }
+ }
+
+ // methods
+
+ private void Decode (byte[] data)
+ {
+ ASN1 encryptedPrivateKeyInfo = new ASN1 (data);
+ if (encryptedPrivateKeyInfo.Tag != 0x30)
+ throw new CryptographicException ("invalid EncryptedPrivateKeyInfo");
+
+ ASN1 encryptionAlgorithm = encryptedPrivateKeyInfo [0];
+ if (encryptionAlgorithm.Tag != 0x30)
+ throw new CryptographicException ("invalid encryptionAlgorithm");
+ ASN1 algorithm = encryptionAlgorithm [0];
+ if (algorithm.Tag != 0x06)
+ throw new CryptographicException ("invalid algorithm");
+ _algorithm = ASN1Convert.ToOid (algorithm);
+ // parameters ANY DEFINED BY algorithm OPTIONAL
+ if (encryptionAlgorithm.Count > 1) {
+ ASN1 parameters = encryptionAlgorithm [1];
+ if (parameters.Tag != 0x30)
+ throw new CryptographicException ("invalid parameters");
+
+ ASN1 salt = parameters [0];
+ if (salt.Tag != 0x04)
+ throw new CryptographicException ("invalid salt");
+ _salt = salt.Value;
+
+ ASN1 iterationCount = parameters [1];
+ if (iterationCount.Tag != 0x02)
+ throw new CryptographicException ("invalid iterationCount");
+ _iterations = ASN1Convert.ToInt32 (iterationCount);
+ }
+
+ ASN1 encryptedData = encryptedPrivateKeyInfo [1];
+ if (encryptedData.Tag != 0x04)
+ throw new CryptographicException ("invalid EncryptedData");
+ _data = encryptedData.Value;
+ }
+
+ // Note: PKCS#8 doesn't define how to generate the key required for encryption
+ // so you're on your own. Just don't try to copy the big guys too much ;)
+ // Netscape: http://www.cs.auckland.ac.nz/~pgut001/pubs/netscape.txt
+ // Microsoft: http://www.cs.auckland.ac.nz/~pgut001/pubs/breakms.txt
+ public byte[] GetBytes ()
+ {
+ if (_algorithm == null)
+ throw new CryptographicException ("No algorithm OID specified");
+
+ ASN1 encryptionAlgorithm = new ASN1 (0x30);
+ encryptionAlgorithm.Add (ASN1Convert.FromOid (_algorithm));
+
+ // parameters ANY DEFINED BY algorithm OPTIONAL
+ if ((_iterations > 0) || (_salt != null)) {
+ ASN1 salt = new ASN1 (0x04, _salt);
+ ASN1 iterations = ASN1Convert.FromInt32 (_iterations);
+
+ ASN1 parameters = new ASN1 (0x30);
+ parameters.Add (salt);
+ parameters.Add (iterations);
+ encryptionAlgorithm.Add (parameters);
+ }
+
+ // encapsulates EncryptedData into an OCTET STRING
+ ASN1 encryptedData = new ASN1 (0x04, _data);
+
+ ASN1 encryptedPrivateKeyInfo = new ASN1 (0x30);
+ encryptedPrivateKeyInfo.Add (encryptionAlgorithm);
+ encryptedPrivateKeyInfo.Add (encryptedData);
+
+ return encryptedPrivateKeyInfo.GetBytes ();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs b/MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs
new file mode 100644
index 000000000..3f9b90ac1
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/PfxGenerator.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+ public class PFXGenerator
+ {
+ // http://www.freekpaans.nl/2015/04/creating-self-signed-x-509-certificates-using-mono-security/
+ public static byte[] GeneratePfx(string certificateName, string password)
+ {
+ byte[] sn = GenerateSerialNumber();
+ string subject = string.Format("CN={0}", certificateName);
+
+ DateTime notBefore = DateTime.Now;
+ DateTime notAfter = DateTime.Now.AddYears(20);
+
+ RSA subjectKey = new RSACryptoServiceProvider(2048);
+
+
+ string hashName = "SHA256";
+
+ X509CertificateBuilder cb = new X509CertificateBuilder(3);
+ cb.SerialNumber = sn;
+ cb.IssuerName = subject;
+ cb.NotBefore = notBefore;
+ cb.NotAfter = notAfter;
+ cb.SubjectName = subject;
+ cb.SubjectPublicKey = subjectKey;
+ cb.Hash = hashName;
+
+ byte[] rawcert = cb.Sign(subjectKey);
+
+
+ PKCS12 p12 = new PKCS12();
+ p12.Password = password;
+
+ Hashtable attributes = GetAttributes();
+
+ p12.AddCertificate(new X509Certificate(rawcert), attributes);
+ p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
+
+ return p12.GetBytes();
+ }
+
+ private static Hashtable GetAttributes()
+ {
+ ArrayList list = new ArrayList();
+ // we use a fixed array to avoid endianess issues
+ // (in case some tools requires the ID to be 1).
+ list.Add(new byte[4] { 1, 0, 0, 0 });
+ Hashtable attributes = new Hashtable(1);
+ attributes.Add(PKCS9.localKeyId, list);
+ return attributes;
+ }
+
+ private static byte[] GenerateSerialNumber()
+ {
+ byte[] sn = Guid.NewGuid().ToByteArray();
+
+ //must be positive
+ if ((sn[0] & 0x80) == 0x80)
+ sn[0] -= 0x80;
+ return sn;
+ }
+
+ public static byte[] GetCertificateForBytes(byte[] pfx, string password)
+ {
+ var pkcs = new PKCS12(pfx, password);
+ var cert = pkcs.GetCertificate(GetAttributes());
+
+ return cert.RawData;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs
new file mode 100644
index 000000000..93e1a6bef
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X501Name.cs
@@ -0,0 +1,393 @@
+//
+// X501Name.cs: X.501 Distinguished Names stuff
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Globalization;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ // References:
+ // 1. Information technology - Open Systems Interconnection - The Directory: Models
+ // http://www.itu.int/rec/recommendation.asp?type=items&lang=e&parent=T-REC-X.501-200102-I
+ // 2. RFC2253: Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names
+ // http://www.ietf.org/rfc/rfc2253.txt
+
+ /*
+ * Name ::= CHOICE { RDNSequence }
+ *
+ * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ *
+ * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
+ */
+ public sealed class X501 {
+
+ static byte[] countryName = { 0x55, 0x04, 0x06 };
+ static byte[] organizationName = { 0x55, 0x04, 0x0A };
+ static byte[] organizationalUnitName = { 0x55, 0x04, 0x0B };
+ static byte[] commonName = { 0x55, 0x04, 0x03 };
+ static byte[] localityName = { 0x55, 0x04, 0x07 };
+ static byte[] stateOrProvinceName = { 0x55, 0x04, 0x08 };
+ static byte[] streetAddress = { 0x55, 0x04, 0x09 };
+ //static byte[] serialNumber = { 0x55, 0x04, 0x05 };
+ static byte[] domainComponent = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19 };
+ static byte[] userid = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01 };
+ static byte[] email = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 };
+ static byte[] dnQualifier = { 0x55, 0x04, 0x2E };
+ static byte[] title = { 0x55, 0x04, 0x0C };
+ static byte[] surname = { 0x55, 0x04, 0x04 };
+ static byte[] givenName = { 0x55, 0x04, 0x2A };
+ static byte[] initial = { 0x55, 0x04, 0x2B };
+
+ private X501 ()
+ {
+ }
+
+ static public string ToString (ASN1 seq)
+ {
+ StringBuilder sb = new StringBuilder ();
+ for (int i = 0; i < seq.Count; i++) {
+ ASN1 entry = seq [i];
+ AppendEntry (sb, entry, true);
+
+ // separator (not on last iteration)
+ if (i < seq.Count - 1)
+ sb.Append (", ");
+ }
+ return sb.ToString ();
+ }
+
+ static public string ToString (ASN1 seq, bool reversed, string separator, bool quotes)
+ {
+ StringBuilder sb = new StringBuilder ();
+
+ if (reversed) {
+ for (int i = seq.Count - 1; i >= 0; i--) {
+ ASN1 entry = seq [i];
+ AppendEntry (sb, entry, quotes);
+
+ // separator (not on last iteration)
+ if (i > 0)
+ sb.Append (separator);
+ }
+ } else {
+ for (int i = 0; i < seq.Count; i++) {
+ ASN1 entry = seq [i];
+ AppendEntry (sb, entry, quotes);
+
+ // separator (not on last iteration)
+ if (i < seq.Count - 1)
+ sb.Append (separator);
+ }
+ }
+ return sb.ToString ();
+ }
+
+ static private void AppendEntry (StringBuilder sb, ASN1 entry, bool quotes)
+ {
+ // multiple entries are valid
+ for (int k = 0; k < entry.Count; k++) {
+ ASN1 pair = entry [k];
+ ASN1 s = pair [1];
+ if (s == null)
+ continue;
+
+ ASN1 poid = pair [0];
+ if (poid == null)
+ continue;
+
+ if (poid.CompareValue (countryName))
+ sb.Append ("C=");
+ else if (poid.CompareValue (organizationName))
+ sb.Append ("O=");
+ else if (poid.CompareValue (organizationalUnitName))
+ sb.Append ("OU=");
+ else if (poid.CompareValue (commonName))
+ sb.Append ("CN=");
+ else if (poid.CompareValue (localityName))
+ sb.Append ("L=");
+ else if (poid.CompareValue (stateOrProvinceName))
+ sb.Append ("S="); // NOTE: RFC2253 uses ST=
+ else if (poid.CompareValue (streetAddress))
+ sb.Append ("STREET=");
+ else if (poid.CompareValue (domainComponent))
+ sb.Append ("DC=");
+ else if (poid.CompareValue (userid))
+ sb.Append ("UID=");
+ else if (poid.CompareValue (email))
+ sb.Append ("E="); // NOTE: Not part of RFC2253
+ else if (poid.CompareValue (dnQualifier))
+ sb.Append ("dnQualifier=");
+ else if (poid.CompareValue (title))
+ sb.Append ("T=");
+ else if (poid.CompareValue (surname))
+ sb.Append ("SN=");
+ else if (poid.CompareValue (givenName))
+ sb.Append ("G=");
+ else if (poid.CompareValue (initial))
+ sb.Append ("I=");
+ else {
+ // unknown OID
+ sb.Append ("OID."); // NOTE: Not present as RFC2253
+ sb.Append (ASN1Convert.ToOid (poid));
+ sb.Append ("=");
+ }
+
+ string sValue = null;
+ // 16bits or 8bits string ? TODO not complete (+special chars!)
+ if (s.Tag == 0x1E) {
+ // BMPSTRING
+ StringBuilder sb2 = new StringBuilder ();
+ for (int j = 1; j < s.Value.Length; j += 2)
+ sb2.Append ((char)s.Value[j]);
+ sValue = sb2.ToString ();
+ } else {
+ if (s.Tag == 0x14)
+ sValue = Encoding.UTF7.GetString (s.Value);
+ else
+ sValue = Encoding.UTF8.GetString (s.Value);
+ // in some cases we must quote (") the value
+ // Note: this doesn't seems to conform to RFC2253
+ char[] specials = { ',', '+', '"', '\\', '<', '>', ';' };
+ if (quotes) {
+ if ((sValue.IndexOfAny (specials, 0, sValue.Length) > 0) ||
+ sValue.StartsWith (" ") || (sValue.EndsWith (" ")))
+ sValue = "\"" + sValue + "\"";
+ }
+ }
+
+ sb.Append (sValue);
+
+ // separator (not on last iteration)
+ if (k < entry.Count - 1)
+ sb.Append (", ");
+ }
+ }
+
+ static private X520.AttributeTypeAndValue GetAttributeFromOid (string attributeType)
+ {
+ string s = attributeType.ToUpper (CultureInfo.InvariantCulture).Trim ();
+ switch (s) {
+ case "C":
+ return new X520.CountryName ();
+ case "O":
+ return new X520.OrganizationName ();
+ case "OU":
+ return new X520.OrganizationalUnitName ();
+ case "CN":
+ return new X520.CommonName ();
+ case "L":
+ return new X520.LocalityName ();
+ case "S": // Microsoft
+ case "ST": // RFC2253
+ return new X520.StateOrProvinceName ();
+ case "E": // NOTE: Not part of RFC2253
+ return new X520.EmailAddress ();
+ case "DC": // RFC2247
+ return new X520.DomainComponent ();
+ case "UID": // RFC1274
+ return new X520.UserId ();
+ case "DNQUALIFIER":
+ return new X520.DnQualifier ();
+ case "T":
+ return new X520.Title ();
+ case "SN":
+ return new X520.Surname ();
+ case "G":
+ return new X520.GivenName ();
+ case "I":
+ return new X520.Initial ();
+ default:
+ if (s.StartsWith ("OID.")) {
+ // MUST support it but it OID may be without it
+ return new X520.Oid (s.Substring (4));
+ } else {
+ if (IsOid (s))
+ return new X520.Oid (s);
+ else
+ return null;
+ }
+ }
+ }
+
+ static private bool IsOid (string oid)
+ {
+ try {
+ ASN1 asn = ASN1Convert.FromOid (oid);
+ return (asn.Tag == 0x06);
+ }
+ catch {
+ return false;
+ }
+ }
+
+ // no quote processing
+ static private X520.AttributeTypeAndValue ReadAttribute (string value, ref int pos)
+ {
+ while ((value[pos] == ' ') && (pos < value.Length))
+ pos++;
+
+ // get '=' position in substring
+ int equal = value.IndexOf ('=', pos);
+ if (equal == -1) {
+ string msg = ("No attribute found.");
+ throw new FormatException (msg);
+ }
+
+ string s = value.Substring (pos, equal - pos);
+ X520.AttributeTypeAndValue atv = GetAttributeFromOid (s);
+ if (atv == null) {
+ string msg = ("Unknown attribute '{0}'.");
+ throw new FormatException (String.Format (msg, s));
+ }
+ pos = equal + 1; // skip the '='
+ return atv;
+ }
+
+ static private bool IsHex (char c)
+ {
+ if (Char.IsDigit (c))
+ return true;
+ char up = Char.ToUpper (c, CultureInfo.InvariantCulture);
+ return ((up >= 'A') && (up <= 'F'));
+ }
+
+ static string ReadHex (string value, ref int pos)
+ {
+ StringBuilder sb = new StringBuilder ();
+ // it is (at least an) 8 bits char
+ sb.Append (value[pos++]);
+ sb.Append (value[pos]);
+ // look ahead for a 16 bits char
+ if ((pos < value.Length - 4) && (value[pos+1] == '\\') && IsHex (value[pos+2])) {
+ pos += 2; // pass last char and skip \
+ sb.Append (value[pos++]);
+ sb.Append (value[pos]);
+ }
+ byte[] data = CryptoConvert.FromHex (sb.ToString ());
+ return Encoding.UTF8.GetString (data);
+ }
+
+ static private int ReadEscaped (StringBuilder sb, string value, int pos)
+ {
+ switch (value[pos]) {
+ case '\\':
+ case '"':
+ case '=':
+ case ';':
+ case '<':
+ case '>':
+ case '+':
+ case '#':
+ case ',':
+ sb.Append (value[pos]);
+ return pos;
+ default:
+ if (pos >= value.Length - 2) {
+ string msg = ("Malformed escaped value '{0}'.");
+ throw new FormatException (string.Format (msg, value.Substring (pos)));
+ }
+ // it's either a 8 bits or 16 bits char
+ sb.Append (ReadHex (value, ref pos));
+ return pos;
+ }
+ }
+
+ static private int ReadQuoted (StringBuilder sb, string value, int pos)
+ {
+ int original = pos;
+ while (pos <= value.Length) {
+ switch (value[pos]) {
+ case '"':
+ return pos;
+ case '\\':
+ return ReadEscaped (sb, value, pos);
+ default:
+ sb.Append (value[pos]);
+ pos++;
+ break;
+ }
+ }
+ string msg = ("Malformed quoted value '{0}'.");
+ throw new FormatException (string.Format (msg, value.Substring (original)));
+ }
+
+ static private string ReadValue (string value, ref int pos)
+ {
+ int original = pos;
+ StringBuilder sb = new StringBuilder ();
+ while (pos < value.Length) {
+ switch (value [pos]) {
+ case '\\':
+ pos = ReadEscaped (sb, value, ++pos);
+ break;
+ case '"':
+ pos = ReadQuoted (sb, value, ++pos);
+ break;
+ case '=':
+ case ';':
+ case '<':
+ case '>':
+ string msg =("Malformed value '{0}' contains '{1}' outside quotes.");
+ throw new FormatException (string.Format (msg, value.Substring (original), value[pos]));
+ case '+':
+ case '#':
+ throw new NotImplementedException ();
+ case ',':
+ pos++;
+ return sb.ToString ();
+ default:
+ sb.Append (value[pos]);
+ break;
+ }
+ pos++;
+ }
+ return sb.ToString ();
+ }
+
+ static public ASN1 FromString (string rdn)
+ {
+ if (rdn == null)
+ throw new ArgumentNullException ("rdn");
+
+ int pos = 0;
+ ASN1 asn1 = new ASN1 (0x30);
+ while (pos < rdn.Length) {
+ X520.AttributeTypeAndValue atv = ReadAttribute (rdn, ref pos);
+ atv.Value = ReadValue (rdn, ref pos);
+
+ ASN1 sequence = new ASN1 (0x31);
+ sequence.Add (atv.GetASN1 ());
+ asn1.Add (sequence);
+ }
+ return asn1;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs
new file mode 100644
index 000000000..e16855959
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Builder.cs
@@ -0,0 +1,153 @@
+//
+// X509Builder.cs: Abstract builder class for X509 objects
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// (C) 2004 Novell (http://www.novell.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Globalization;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ public abstract class X509Builder {
+
+ private const string defaultHash = "SHA1";
+ private string hashName;
+
+ protected X509Builder ()
+ {
+ hashName = defaultHash;
+ }
+
+ protected abstract ASN1 ToBeSigned (string hashName);
+
+ // move to PKCS1
+ protected string GetOid (string hashName)
+ {
+ switch (hashName.ToLower (CultureInfo.InvariantCulture)) {
+ case "md2":
+ // md2withRSAEncryption (1 2 840 113549 1 1 2)
+ return "1.2.840.113549.1.1.2";
+ case "md4":
+ // md4withRSAEncryption (1 2 840 113549 1 1 3)
+ return "1.2.840.113549.1.1.3";
+ case "md5":
+ // md5withRSAEncryption (1 2 840 113549 1 1 4)
+ return "1.2.840.113549.1.1.4";
+ case "sha1":
+ // sha1withRSAEncryption (1 2 840 113549 1 1 5)
+ return "1.2.840.113549.1.1.5";
+ case "sha256":
+ // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+ return "1.2.840.113549.1.1.11";
+ case "sha384":
+ // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+ return "1.2.840.113549.1.1.12";
+ case "sha512":
+ // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+ return "1.2.840.113549.1.1.13";
+ default:
+ throw new NotSupportedException ("Unknown hash algorithm " + hashName);
+ }
+ }
+
+ public string Hash {
+ get { return hashName; }
+ set {
+ if (hashName == null)
+ hashName = defaultHash;
+ else
+ hashName = value;
+ }
+ }
+
+ public virtual byte[] Sign (AsymmetricAlgorithm aa)
+ {
+ if (aa is RSA)
+ return Sign (aa as RSA);
+ else if (aa is DSA)
+ return Sign (aa as DSA);
+ else
+ throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString());
+ }
+
+ private byte[] Build (ASN1 tbs, string hashoid, byte[] signature)
+ {
+ ASN1 builder = new ASN1 (0x30);
+ builder.Add (tbs);
+ builder.Add (PKCS7.AlgorithmIdentifier (hashoid));
+ // first byte of BITSTRING is the number of unused bits in the first byte
+ byte[] bitstring = new byte [signature.Length + 1];
+ Buffer.BlockCopy (signature, 0, bitstring, 1, signature.Length);
+ builder.Add (new ASN1 (0x03, bitstring));
+ return builder.GetBytes ();
+ }
+
+ public virtual byte[] Sign (RSA key)
+ {
+ string oid = GetOid (hashName);
+ ASN1 tbs = ToBeSigned (oid);
+ HashAlgorithm ha = HashAlgorithm.Create (hashName);
+ byte[] hash = ha.ComputeHash (tbs.GetBytes ());
+
+ RSAPKCS1SignatureFormatter pkcs1 = new RSAPKCS1SignatureFormatter (key);
+ pkcs1.SetHashAlgorithm (hashName);
+ byte[] signature = pkcs1.CreateSignature (hash);
+
+ return Build (tbs, oid, signature);
+ }
+
+ public virtual byte[] Sign (DSA key)
+ {
+ string oid = "1.2.840.10040.4.3";
+ ASN1 tbs = ToBeSigned (oid);
+ HashAlgorithm ha = HashAlgorithm.Create (hashName);
+ if (!(ha is SHA1))
+ throw new NotSupportedException ("Only SHA-1 is supported for DSA");
+ byte[] hash = ha.ComputeHash (tbs.GetBytes ());
+
+ DSASignatureFormatter dsa = new DSASignatureFormatter (key);
+ dsa.SetHashAlgorithm (hashName);
+ byte[] rs = dsa.CreateSignature (hash);
+
+ // split R and S
+ byte[] r = new byte [20];
+ Buffer.BlockCopy (rs, 0, r, 0, 20);
+ byte[] s = new byte [20];
+ Buffer.BlockCopy (rs, 20, s, 0, 20);
+ ASN1 signature = new ASN1 (0x30);
+ signature.Add (new ASN1 (0x02, r));
+ signature.Add (new ASN1 (0x02, s));
+
+ // dsaWithSha1 (1 2 840 10040 4 3)
+ return Build (tbs, oid, signature.GetBytes ());
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs
new file mode 100644
index 000000000..f49445f0e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Certificate.cs
@@ -0,0 +1,563 @@
+//
+// X509Certificates.cs: Handles X.509 certificates.
+//
+// Author:
+// Sebastien Pouliot <sebastien@xamarin.com>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
+// Copyright 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Runtime.Serialization;
+using System.Security.Cryptography;
+using System.Security.Permissions;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ // References:
+ // a. Internet X.509 Public Key Infrastructure Certificate and CRL Profile
+ // http://www.ietf.org/rfc/rfc3280.txt
+ // b. ITU ASN.1 standards (free download)
+ // http://www.itu.int/ITU-T/studygroups/com17/languages/
+
+ public class X509Certificate : ISerializable
+ {
+
+ private ASN1 decoder;
+
+ private byte[] m_encodedcert;
+ private DateTime m_from;
+ private DateTime m_until;
+ private ASN1 issuer;
+ private string m_issuername;
+ private string m_keyalgo;
+ private byte[] m_keyalgoparams;
+ private ASN1 subject;
+ private string m_subject;
+ private byte[] m_publickey;
+ private byte[] signature;
+ private string m_signaturealgo;
+ private byte[] m_signaturealgoparams;
+ private byte[] certhash;
+ private RSA _rsa;
+ private DSA _dsa;
+
+ // from http://msdn.microsoft.com/en-gb/library/ff635835.aspx
+ private const string OID_DSA = "1.2.840.10040.4.1";
+ private const string OID_RSA = "1.2.840.113549.1.1.1";
+
+ // from http://www.ietf.org/rfc/rfc2459.txt
+ //
+ //Certificate ::= SEQUENCE {
+ // tbsCertificate TBSCertificate,
+ // signatureAlgorithm AlgorithmIdentifier,
+ // signature BIT STRING }
+ //
+ //TBSCertificate ::= SEQUENCE {
+ // version [0] Version DEFAULT v1,
+ // serialNumber CertificateSerialNumber,
+ // signature AlgorithmIdentifier,
+ // issuer Name,
+ // validity Validity,
+ // subject Name,
+ // subjectPublicKeyInfo SubjectPublicKeyInfo,
+ // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ // -- If present, version shall be v2 or v3
+ // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
+ // -- If present, version shall be v2 or v3
+ // extensions [3] Extensions OPTIONAL
+ // -- If present, version shall be v3 -- }
+ private int version;
+ private byte[] serialnumber;
+
+ private byte[] issuerUniqueID;
+ private byte[] subjectUniqueID;
+ private X509ExtensionCollection extensions;
+
+ private static string encoding_error = ("Input data cannot be coded as a valid certificate.");
+
+
+ // that's were the real job is!
+ private void Parse (byte[] data)
+ {
+ try {
+ decoder = new ASN1 (data);
+ // Certificate
+ if (decoder.Tag != 0x30)
+ throw new CryptographicException (encoding_error);
+ // Certificate / TBSCertificate
+ if (decoder [0].Tag != 0x30)
+ throw new CryptographicException (encoding_error);
+
+ ASN1 tbsCertificate = decoder [0];
+
+ int tbs = 0;
+ // Certificate / TBSCertificate / Version
+ ASN1 v = decoder [0][tbs];
+ version = 1; // DEFAULT v1
+ if ((v.Tag == 0xA0) && (v.Count > 0)) {
+ // version (optional) is present only in v2+ certs
+ version += v [0].Value [0]; // zero based
+ tbs++;
+ }
+
+ // Certificate / TBSCertificate / CertificateSerialNumber
+ ASN1 sn = decoder [0][tbs++];
+ if (sn.Tag != 0x02)
+ throw new CryptographicException (encoding_error);
+ serialnumber = sn.Value;
+ Array.Reverse (serialnumber, 0, serialnumber.Length);
+
+ // Certificate / TBSCertificate / AlgorithmIdentifier
+ tbs++;
+ // ASN1 signatureAlgo = tbsCertificate.Element (tbs++, 0x30);
+
+ issuer = tbsCertificate.Element (tbs++, 0x30);
+ m_issuername = X501.ToString (issuer);
+
+ ASN1 validity = tbsCertificate.Element (tbs++, 0x30);
+ ASN1 notBefore = validity [0];
+ m_from = ASN1Convert.ToDateTime (notBefore);
+ ASN1 notAfter = validity [1];
+ m_until = ASN1Convert.ToDateTime (notAfter);
+
+ subject = tbsCertificate.Element (tbs++, 0x30);
+ m_subject = X501.ToString (subject);
+
+ ASN1 subjectPublicKeyInfo = tbsCertificate.Element (tbs++, 0x30);
+
+ ASN1 algorithm = subjectPublicKeyInfo.Element (0, 0x30);
+ ASN1 algo = algorithm.Element (0, 0x06);
+ m_keyalgo = ASN1Convert.ToOid (algo);
+ // parameters ANY DEFINED BY algorithm OPTIONAL
+ // so we dont ask for a specific (Element) type and return DER
+ ASN1 parameters = algorithm [1];
+ m_keyalgoparams = ((algorithm.Count > 1) ? parameters.GetBytes () : null);
+
+ ASN1 subjectPublicKey = subjectPublicKeyInfo.Element (1, 0x03);
+ // we must drop th first byte (which is the number of unused bits
+ // in the BITSTRING)
+ int n = subjectPublicKey.Length - 1;
+ m_publickey = new byte [n];
+ Buffer.BlockCopy (subjectPublicKey.Value, 1, m_publickey, 0, n);
+
+ // signature processing
+ byte[] bitstring = decoder [2].Value;
+ // first byte contains unused bits in first byte
+ signature = new byte [bitstring.Length - 1];
+ Buffer.BlockCopy (bitstring, 1, signature, 0, signature.Length);
+
+ algorithm = decoder [1];
+ algo = algorithm.Element (0, 0x06);
+ m_signaturealgo = ASN1Convert.ToOid (algo);
+ parameters = algorithm [1];
+ if (parameters != null)
+ m_signaturealgoparams = parameters.GetBytes ();
+ else
+ m_signaturealgoparams = null;
+
+ // Certificate / TBSCertificate / issuerUniqueID
+ ASN1 issuerUID = tbsCertificate.Element (tbs, 0x81);
+ if (issuerUID != null) {
+ tbs++;
+ issuerUniqueID = issuerUID.Value;
+ }
+
+ // Certificate / TBSCertificate / subjectUniqueID
+ ASN1 subjectUID = tbsCertificate.Element (tbs, 0x82);
+ if (subjectUID != null) {
+ tbs++;
+ subjectUniqueID = subjectUID.Value;
+ }
+
+ // Certificate / TBSCertificate / Extensions
+ ASN1 extns = tbsCertificate.Element (tbs, 0xA3);
+ if ((extns != null) && (extns.Count == 1))
+ extensions = new X509ExtensionCollection (extns [0]);
+ else
+ extensions = new X509ExtensionCollection (null);
+
+ // keep a copy of the original data
+ m_encodedcert = (byte[]) data.Clone ();
+ }
+ catch (Exception ex) {
+ throw new CryptographicException (encoding_error, ex);
+ }
+ }
+
+ // constructors
+
+ public X509Certificate (byte[] data)
+ {
+ if (data != null) {
+ // does it looks like PEM ?
+ if ((data.Length > 0) && (data [0] != 0x30)) {
+ try {
+ data = PEM ("CERTIFICATE", data);
+ }
+ catch (Exception ex) {
+ throw new CryptographicException (encoding_error, ex);
+ }
+ }
+ Parse (data);
+ }
+ }
+
+ private byte[] GetUnsignedBigInteger (byte[] integer)
+ {
+ if (integer [0] == 0x00) {
+ // this first byte is added so we're sure it's an unsigned integer
+ // however we can't feed it into RSAParameters or DSAParameters
+ int length = integer.Length - 1;
+ byte[] uinteger = new byte [length];
+ Buffer.BlockCopy (integer, 1, uinteger, 0, length);
+ return uinteger;
+ }
+ else
+ return integer;
+ }
+
+ // public methods
+
+ public DSA DSA {
+ get {
+ if (m_keyalgoparams == null)
+ throw new CryptographicException ("Missing key algorithm parameters.");
+
+ if (_dsa == null && m_keyalgo == OID_DSA) {
+ DSAParameters dsaParams = new DSAParameters ();
+ // for DSA m_publickey contains 1 ASN.1 integer - Y
+ ASN1 pubkey = new ASN1 (m_publickey);
+ if ((pubkey == null) || (pubkey.Tag != 0x02))
+ return null;
+ dsaParams.Y = GetUnsignedBigInteger (pubkey.Value);
+
+ ASN1 param = new ASN1 (m_keyalgoparams);
+ if ((param == null) || (param.Tag != 0x30) || (param.Count < 3))
+ return null;
+ if ((param [0].Tag != 0x02) || (param [1].Tag != 0x02) || (param [2].Tag != 0x02))
+ return null;
+ dsaParams.P = GetUnsignedBigInteger (param [0].Value);
+ dsaParams.Q = GetUnsignedBigInteger (param [1].Value);
+ dsaParams.G = GetUnsignedBigInteger (param [2].Value);
+
+ // BUG: MS BCL 1.0 can't import a key which
+ // isn't the same size as the one present in
+ // the container.
+ _dsa = (DSA) new DSACryptoServiceProvider (dsaParams.Y.Length << 3);
+ _dsa.ImportParameters (dsaParams);
+ }
+ return _dsa;
+ }
+
+ set {
+ _dsa = value;
+ if (value != null)
+ _rsa = null;
+ }
+ }
+
+ public X509ExtensionCollection Extensions {
+ get { return extensions; }
+ }
+
+ public byte[] Hash {
+ get {
+ if (certhash == null) {
+ if ((decoder == null) || (decoder.Count < 1))
+ return null;
+ string algo = PKCS1.HashNameFromOid (m_signaturealgo, false);
+ if (algo == null)
+ return null;
+ byte[] toBeSigned = decoder [0].GetBytes ();
+ using (var hash = PKCS1.CreateFromName (algo))
+ certhash = hash.ComputeHash (toBeSigned, 0, toBeSigned.Length);
+ }
+ return (byte[]) certhash.Clone ();
+ }
+ }
+
+ public virtual string IssuerName {
+ get { return m_issuername; }
+ }
+
+ public virtual string KeyAlgorithm {
+ get { return m_keyalgo; }
+ }
+
+ public virtual byte[] KeyAlgorithmParameters {
+ get {
+ if (m_keyalgoparams == null)
+ return null;
+ return (byte[]) m_keyalgoparams.Clone ();
+ }
+ set { m_keyalgoparams = value; }
+ }
+
+ public virtual byte[] PublicKey {
+ get {
+ if (m_publickey == null)
+ return null;
+ return (byte[]) m_publickey.Clone ();
+ }
+ }
+
+ public virtual RSA RSA {
+ get {
+ if (_rsa == null && m_keyalgo == OID_RSA) {
+ RSAParameters rsaParams = new RSAParameters ();
+ // for RSA m_publickey contains 2 ASN.1 integers
+ // the modulus and the public exponent
+ ASN1 pubkey = new ASN1 (m_publickey);
+ ASN1 modulus = pubkey [0];
+ if ((modulus == null) || (modulus.Tag != 0x02))
+ return null;
+ ASN1 exponent = pubkey [1];
+ if (exponent.Tag != 0x02)
+ return null;
+
+ rsaParams.Modulus = GetUnsignedBigInteger (modulus.Value);
+ rsaParams.Exponent = exponent.Value;
+
+ // BUG: MS BCL 1.0 can't import a key which
+ // isn't the same size as the one present in
+ // the container.
+ int keySize = (rsaParams.Modulus.Length << 3);
+ _rsa = (RSA) new RSACryptoServiceProvider (keySize);
+ _rsa.ImportParameters (rsaParams);
+ }
+ return _rsa;
+ }
+
+ set {
+ if (value != null)
+ _dsa = null;
+ _rsa = value;
+ }
+ }
+
+ public virtual byte[] RawData {
+ get {
+ if (m_encodedcert == null)
+ return null;
+ return (byte[]) m_encodedcert.Clone ();
+ }
+ }
+
+ public virtual byte[] SerialNumber {
+ get {
+ if (serialnumber == null)
+ return null;
+ return (byte[]) serialnumber.Clone ();
+ }
+ }
+
+ public virtual byte[] Signature {
+ get {
+ if (signature == null)
+ return null;
+
+ switch (m_signaturealgo) {
+ case "1.2.840.113549.1.1.2": // MD2 with RSA encryption
+ case "1.2.840.113549.1.1.3": // MD4 with RSA encryption
+ case "1.2.840.113549.1.1.4": // MD5 with RSA encryption
+ case "1.2.840.113549.1.1.5": // SHA-1 with RSA Encryption
+ case "1.3.14.3.2.29": // SHA1 with RSA signature
+ case "1.2.840.113549.1.1.11": // SHA-256 with RSA Encryption
+ case "1.2.840.113549.1.1.12": // SHA-384 with RSA Encryption
+ case "1.2.840.113549.1.1.13": // SHA-512 with RSA Encryption
+ case "1.3.36.3.3.1.2": // RIPEMD160 with RSA Encryption
+ return (byte[]) signature.Clone ();
+
+ case "1.2.840.10040.4.3": // SHA-1 with DSA
+ ASN1 sign = new ASN1 (signature);
+ if ((sign == null) || (sign.Count != 2))
+ return null;
+ byte[] part1 = sign [0].Value;
+ byte[] part2 = sign [1].Value;
+ byte[] sig = new byte [40];
+ // parts may be less than 20 bytes (i.e. first bytes were 0x00)
+ // parts may be more than 20 bytes (i.e. first byte > 0x80, negative)
+ int s1 = System.Math.Max (0, part1.Length - 20);
+ int e1 = System.Math.Max (0, 20 - part1.Length);
+ Buffer.BlockCopy (part1, s1, sig, e1, part1.Length - s1);
+ int s2 = System.Math.Max (0, part2.Length - 20);
+ int e2 = System.Math.Max (20, 40 - part2.Length);
+ Buffer.BlockCopy (part2, s2, sig, e2, part2.Length - s2);
+ return sig;
+
+ default:
+ throw new CryptographicException ("Unsupported hash algorithm: " + m_signaturealgo);
+ }
+ }
+ }
+
+ public virtual string SignatureAlgorithm {
+ get { return m_signaturealgo; }
+ }
+
+ public virtual byte[] SignatureAlgorithmParameters {
+ get {
+ if (m_signaturealgoparams == null)
+ return m_signaturealgoparams;
+ return (byte[]) m_signaturealgoparams.Clone ();
+ }
+ }
+
+ public virtual string SubjectName {
+ get { return m_subject; }
+ }
+
+ public virtual DateTime ValidFrom {
+ get { return m_from; }
+ }
+
+ public virtual DateTime ValidUntil {
+ get { return m_until; }
+ }
+
+ public int Version {
+ get { return version; }
+ }
+
+ public bool IsCurrent {
+ get { return WasCurrent (DateTime.UtcNow); }
+ }
+
+ public bool WasCurrent (DateTime instant)
+ {
+ return ((instant > ValidFrom) && (instant <= ValidUntil));
+ }
+
+ // uncommon v2 "extension"
+ public byte[] IssuerUniqueIdentifier {
+ get {
+ if (issuerUniqueID == null)
+ return null;
+ return (byte[]) issuerUniqueID.Clone ();
+ }
+ }
+
+ // uncommon v2 "extension"
+ public byte[] SubjectUniqueIdentifier {
+ get {
+ if (subjectUniqueID == null)
+ return null;
+ return (byte[]) subjectUniqueID.Clone ();
+ }
+ }
+
+ internal bool VerifySignature (DSA dsa)
+ {
+ // signatureOID is check by both this.Hash and this.Signature
+ DSASignatureDeformatter v = new DSASignatureDeformatter (dsa);
+ // only SHA-1 is supported
+ v.SetHashAlgorithm ("SHA1");
+ return v.VerifySignature (this.Hash, this.Signature);
+ }
+
+ internal bool VerifySignature (RSA rsa)
+ {
+ // SHA1-1 with DSA
+ if (m_signaturealgo == "1.2.840.10040.4.3")
+ return false;
+ RSAPKCS1SignatureDeformatter v = new RSAPKCS1SignatureDeformatter (rsa);
+ v.SetHashAlgorithm (PKCS1.HashNameFromOid (m_signaturealgo));
+ return v.VerifySignature (this.Hash, this.Signature);
+ }
+
+ public bool VerifySignature (AsymmetricAlgorithm aa)
+ {
+ if (aa == null)
+ throw new ArgumentNullException ("aa");
+
+ if (aa is RSA)
+ return VerifySignature (aa as RSA);
+ else if (aa is DSA)
+ return VerifySignature (aa as DSA);
+ else
+ throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ());
+ }
+
+ public bool CheckSignature (byte[] hash, string hashAlgorithm, byte[] signature)
+ {
+ RSACryptoServiceProvider r = (RSACryptoServiceProvider) RSA;
+ return r.VerifyHash (hash, hashAlgorithm, signature);
+ }
+
+ public bool IsSelfSigned {
+ get {
+ if (m_issuername != m_subject)
+ return false;
+
+ try {
+ if (RSA != null)
+ return VerifySignature (RSA);
+ else if (DSA != null)
+ return VerifySignature (DSA);
+ else
+ return false; // e.g. a certificate with only DSA parameters
+ }
+ catch (CryptographicException) {
+ return false;
+ }
+ }
+ }
+
+ public ASN1 GetIssuerName ()
+ {
+ return issuer;
+ }
+
+ public ASN1 GetSubjectName ()
+ {
+ return subject;
+ }
+
+ protected X509Certificate (SerializationInfo info, StreamingContext context)
+ {
+ Parse ((byte[]) info.GetValue ("raw", typeof (byte[])));
+ }
+
+ [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)]
+ public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue ("raw", m_encodedcert);
+ // note: we NEVER serialize the private key
+ }
+
+ static byte[] PEM (string type, byte[] data)
+ {
+ string pem = Encoding.ASCII.GetString (data);
+ string header = String.Format ("-----BEGIN {0}-----", type);
+ string footer = String.Format ("-----END {0}-----", type);
+ int start = pem.IndexOf (header) + header.Length;
+ int end = pem.IndexOf (footer, start);
+ string base64 = pem.Substring (start, (end - start));
+ return Convert.FromBase64String (base64);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs
new file mode 100644
index 000000000..fb6f8ec72
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateBuilder.cs
@@ -0,0 +1,245 @@
+//
+// X509CertificateBuilder.cs: Handles building of X.509 certificates.
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// (C) 2004 Novell (http://www.novell.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Security.Cryptography;
+
+namespace Emby.Common.Implementations.Security
+{
+ // From RFC3280
+ /*
+ * Certificate ::= SEQUENCE {
+ * tbsCertificate TBSCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ * TBSCertificate ::= SEQUENCE {
+ * version [0] Version DEFAULT v1,
+ * serialNumber CertificateSerialNumber,
+ * signature AlgorithmIdentifier,
+ * issuer Name,
+ * validity Validity,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ * -- If present, version MUST be v2 or v3
+ * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
+ * -- If present, version MUST be v2 or v3
+ * extensions [3] Extensions OPTIONAL
+ * -- If present, version MUST be v3 --
+ * }
+ * Version ::= INTEGER { v1(0), v2(1), v3(2) }
+ * CertificateSerialNumber ::= INTEGER
+ * Validity ::= SEQUENCE {
+ * notBefore Time,
+ * notAfter Time
+ * }
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime
+ * }
+ */
+ public class X509CertificateBuilder : X509Builder {
+
+ private byte version;
+ private byte[] sn;
+ private string issuer;
+ private DateTime notBefore;
+ private DateTime notAfter;
+ private string subject;
+ private AsymmetricAlgorithm aa;
+ private byte[] issuerUniqueID;
+ private byte[] subjectUniqueID;
+ private X509ExtensionCollection extensions;
+
+ public X509CertificateBuilder () : this (3) {}
+
+ public X509CertificateBuilder (byte version)
+ {
+ if (version > 3)
+ throw new ArgumentException ("Invalid certificate version");
+ this.version = version;
+ extensions = new X509ExtensionCollection ();
+ }
+
+ public byte Version {
+ get { return version; }
+ set { version = value; }
+ }
+
+ public byte[] SerialNumber {
+ get { return sn; }
+ set { sn = value; }
+ }
+
+ public string IssuerName {
+ get { return issuer; }
+ set { issuer = value; }
+ }
+
+ public DateTime NotBefore {
+ get { return notBefore; }
+ set { notBefore = value; }
+ }
+
+ public DateTime NotAfter {
+ get { return notAfter; }
+ set { notAfter = value; }
+ }
+
+ public string SubjectName {
+ get { return subject; }
+ set { subject = value; }
+ }
+
+ public AsymmetricAlgorithm SubjectPublicKey {
+ get { return aa; }
+ set { aa = value; }
+ }
+
+ public byte[] IssuerUniqueId {
+ get { return issuerUniqueID; }
+ set { issuerUniqueID = value; }
+ }
+
+ public byte[] SubjectUniqueId {
+ get { return subjectUniqueID; }
+ set { subjectUniqueID = value; }
+ }
+
+ public X509ExtensionCollection Extensions {
+ get { return extensions; }
+ }
+
+
+ /* SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ */
+ private ASN1 SubjectPublicKeyInfo ()
+ {
+ ASN1 keyInfo = new ASN1 (0x30);
+ if (aa is RSA) {
+ keyInfo.Add (PKCS7.AlgorithmIdentifier ("1.2.840.113549.1.1.1"));
+ RSAParameters p = (aa as RSA).ExportParameters (false);
+ /* RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER } -- e
+ */
+ ASN1 key = new ASN1 (0x30);
+ key.Add (ASN1Convert.FromUnsignedBigInteger (p.Modulus));
+ key.Add (ASN1Convert.FromUnsignedBigInteger (p.Exponent));
+ keyInfo.Add (new ASN1 (UniqueIdentifier (key.GetBytes ())));
+ }
+ else if (aa is DSA) {
+ DSAParameters p = (aa as DSA).ExportParameters (false);
+ /* Dss-Parms ::= SEQUENCE {
+ * p INTEGER,
+ * q INTEGER,
+ * g INTEGER }
+ */
+ ASN1 param = new ASN1 (0x30);
+ param.Add (ASN1Convert.FromUnsignedBigInteger (p.P));
+ param.Add (ASN1Convert.FromUnsignedBigInteger (p.Q));
+ param.Add (ASN1Convert.FromUnsignedBigInteger (p.G));
+ keyInfo.Add (PKCS7.AlgorithmIdentifier ("1.2.840.10040.4.1", param));
+ ASN1 key = keyInfo.Add (new ASN1 (0x03));
+ // DSAPublicKey ::= INTEGER -- public key, y
+ key.Add (ASN1Convert.FromUnsignedBigInteger (p.Y));
+ }
+ else
+ throw new NotSupportedException ("Unknown Asymmetric Algorithm " + aa.ToString ());
+ return keyInfo;
+ }
+
+ private byte[] UniqueIdentifier (byte[] id)
+ {
+ // UniqueIdentifier ::= BIT STRING
+ ASN1 uid = new ASN1 (0x03);
+ // first byte in a BITSTRING is the number of unused bits in the first byte
+ byte[] v = new byte [id.Length + 1];
+ Buffer.BlockCopy (id, 0, v, 1, id.Length);
+ uid.Value = v;
+ return uid.GetBytes ();
+ }
+
+ protected override ASN1 ToBeSigned (string oid)
+ {
+ // TBSCertificate
+ ASN1 tbsCert = new ASN1 (0x30);
+
+ if (version > 1) {
+ // TBSCertificate / [0] Version DEFAULT v1,
+ byte[] ver = { (byte)(version - 1) };
+ ASN1 v = tbsCert.Add (new ASN1 (0xA0));
+ v.Add (new ASN1 (0x02, ver));
+ }
+
+ // TBSCertificate / CertificateSerialNumber,
+ tbsCert.Add (new ASN1 (0x02, sn));
+
+ // TBSCertificate / AlgorithmIdentifier,
+ tbsCert.Add (PKCS7.AlgorithmIdentifier (oid));
+
+ // TBSCertificate / Name
+ tbsCert.Add (X501.FromString (issuer));
+
+ // TBSCertificate / Validity
+ ASN1 validity = tbsCert.Add (new ASN1 (0x30));
+ // TBSCertificate / Validity / Time
+ validity.Add (ASN1Convert.FromDateTime (notBefore));
+ // TBSCertificate / Validity / Time
+ validity.Add (ASN1Convert.FromDateTime (notAfter));
+
+ // TBSCertificate / Name
+ tbsCert.Add (X501.FromString (subject));
+
+ // TBSCertificate / SubjectPublicKeyInfo
+ tbsCert.Add (SubjectPublicKeyInfo ());
+
+ if (version > 1) {
+ // TBSCertificate / [1] IMPLICIT UniqueIdentifier OPTIONAL
+ if (issuerUniqueID != null)
+ tbsCert.Add (new ASN1 (0xA1, UniqueIdentifier (issuerUniqueID)));
+
+ // TBSCertificate / [2] IMPLICIT UniqueIdentifier OPTIONAL
+ if (subjectUniqueID != null)
+ tbsCert.Add (new ASN1 (0xA1, UniqueIdentifier (subjectUniqueID)));
+
+ // TBSCertificate / [3] Extensions OPTIONAL
+ if ((version > 2) && (extensions.Count > 0))
+ tbsCert.Add (new ASN1 (0xA3, extensions.GetBytes ()));
+ }
+
+ return tbsCert;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs
new file mode 100644
index 000000000..5d353f9cf
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509CertificateCollection.cs
@@ -0,0 +1,201 @@
+//
+// Based on System.Security.Cryptography.X509Certificates.X509CertificateCollection
+// in System assembly
+//
+// Authors:
+// Lawrence Pit (loz@cable.a2000.nl)
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ [Serializable]
+ public class X509CertificateCollection : CollectionBase, IEnumerable {
+
+ public X509CertificateCollection ()
+ {
+ }
+
+ public X509CertificateCollection (X509Certificate [] value)
+ {
+ AddRange (value);
+ }
+
+ public X509CertificateCollection (X509CertificateCollection value)
+ {
+ AddRange (value);
+ }
+
+ // Properties
+
+ public X509Certificate this [int index] {
+ get { return (X509Certificate) InnerList [index]; }
+ set { InnerList [index] = value; }
+ }
+
+ // Methods
+
+ public int Add (X509Certificate value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ return InnerList.Add (value);
+ }
+
+ public void AddRange (X509Certificate [] value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ for (int i = 0; i < value.Length; i++)
+ InnerList.Add (value [i]);
+ }
+
+ public void AddRange (X509CertificateCollection value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ for (int i = 0; i < value.InnerList.Count; i++)
+ InnerList.Add (value [i]);
+ }
+
+ public bool Contains (X509Certificate value)
+ {
+ return (IndexOf (value) != -1);
+ }
+
+ public void CopyTo (X509Certificate[] array, int index)
+ {
+ InnerList.CopyTo (array, index);
+ }
+
+ public new X509CertificateEnumerator GetEnumerator ()
+ {
+ return new X509CertificateEnumerator (this);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return InnerList.GetEnumerator ();
+ }
+
+ public override int GetHashCode ()
+ {
+ return InnerList.GetHashCode ();
+ }
+
+ public int IndexOf (X509Certificate value)
+ {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ byte[] hash = value.Hash;
+ for (int i=0; i < InnerList.Count; i++) {
+ X509Certificate x509 = (X509Certificate) InnerList [i];
+ if (Compare (x509.Hash, hash))
+ return i;
+ }
+ return -1;
+ }
+
+ public void Insert (int index, X509Certificate value)
+ {
+ InnerList.Insert (index, value);
+ }
+
+ public void Remove (X509Certificate value)
+ {
+ InnerList.Remove (value);
+ }
+
+ // private stuff
+
+ private bool Compare (byte[] array1, byte[] array2)
+ {
+ if ((array1 == null) && (array2 == null))
+ return true;
+ if ((array1 == null) || (array2 == null))
+ return false;
+ if (array1.Length != array2.Length)
+ return false;
+ for (int i=0; i < array1.Length; i++) {
+ if (array1 [i] != array2 [i])
+ return false;
+ }
+ return true;
+ }
+
+ // Inner Class
+
+ public class X509CertificateEnumerator : IEnumerator {
+
+ private IEnumerator enumerator;
+
+ // Constructors
+
+ public X509CertificateEnumerator (X509CertificateCollection mappings)
+ {
+ enumerator = ((IEnumerable) mappings).GetEnumerator ();
+ }
+
+ // Properties
+
+ public X509Certificate Current {
+ get { return (X509Certificate) enumerator.Current; }
+ }
+
+ object IEnumerator.Current {
+ get { return enumerator.Current; }
+ }
+
+ // Methods
+
+ bool IEnumerator.MoveNext ()
+ {
+ return enumerator.MoveNext ();
+ }
+
+ void IEnumerator.Reset ()
+ {
+ enumerator.Reset ();
+ }
+
+ public bool MoveNext ()
+ {
+ return enumerator.MoveNext ();
+ }
+
+ public void Reset ()
+ {
+ enumerator.Reset ();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs
new file mode 100644
index 000000000..e82f52bac
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extension.cs
@@ -0,0 +1,208 @@
+//
+// X509Extension.cs: Base class for all X.509 extensions.
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Globalization;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+ /*
+ * Extension ::= SEQUENCE {
+ * extnID OBJECT IDENTIFIER,
+ * critical BOOLEAN DEFAULT FALSE,
+ * extnValue OCTET STRING
+ * }
+ */
+ public class X509Extension {
+
+ protected string extnOid;
+ protected bool extnCritical;
+ protected ASN1 extnValue;
+
+ protected X509Extension ()
+ {
+ extnCritical = false;
+ }
+
+ public X509Extension (ASN1 asn1)
+ {
+ if ((asn1.Tag != 0x30) || (asn1.Count < 2))
+ throw new ArgumentException (("Invalid X.509 extension."));
+ if (asn1[0].Tag != 0x06)
+ throw new ArgumentException (("Invalid X.509 extension."));
+
+ extnOid = ASN1Convert.ToOid (asn1[0]);
+ extnCritical = ((asn1[1].Tag == 0x01) && (asn1[1].Value[0] == 0xFF));
+ // last element is an octet string which may need to be decoded
+ extnValue = asn1 [asn1.Count - 1];
+ if ((extnValue.Tag == 0x04) && (extnValue.Length > 0) && (extnValue.Count == 0)) {
+ try {
+ ASN1 encapsulated = new ASN1 (extnValue.Value);
+ extnValue.Value = null;
+ extnValue.Add (encapsulated);
+ }
+ catch {
+ // data isn't ASN.1
+ }
+ }
+ Decode ();
+ }
+
+ public X509Extension (X509Extension extension)
+ {
+ if (extension == null)
+ throw new ArgumentNullException ("extension");
+ if ((extension.Value == null) || (extension.Value.Tag != 0x04) || (extension.Value.Count != 1))
+ throw new ArgumentException (("Invalid X.509 extension."));
+
+ extnOid = extension.Oid;
+ extnCritical = extension.Critical;
+ extnValue = extension.Value;
+ Decode ();
+ }
+
+ // encode the extension *into* an OCTET STRING
+ protected virtual void Decode ()
+ {
+ }
+
+ // decode the extension from *inside* an OCTET STRING
+ protected virtual void Encode ()
+ {
+ }
+
+ public ASN1 ASN1 {
+ get {
+ ASN1 extension = new ASN1 (0x30);
+ extension.Add (ASN1Convert.FromOid (extnOid));
+ if (extnCritical)
+ extension.Add (new ASN1 (0x01, new byte [1] { 0xFF }));
+ Encode ();
+ extension.Add (extnValue);
+ return extension;
+ }
+ }
+
+ public string Oid {
+ get { return extnOid; }
+ }
+
+ public bool Critical {
+ get { return extnCritical; }
+ set { extnCritical = value; }
+ }
+
+ // this gets overrided with more meaningful names
+ public virtual string Name {
+ get { return extnOid; }
+ }
+
+ public ASN1 Value {
+ get {
+ if (extnValue == null) {
+ Encode ();
+ }
+ return extnValue;
+ }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj == null)
+ return false;
+
+ X509Extension ex = (obj as X509Extension);
+ if (ex == null)
+ return false;
+
+ if (extnCritical != ex.extnCritical)
+ return false;
+ if (extnOid != ex.extnOid)
+ return false;
+ if (extnValue.Length != ex.extnValue.Length)
+ return false;
+
+ for (int i=0; i < extnValue.Length; i++) {
+ if (extnValue [i] != ex.extnValue [i])
+ return false;
+ }
+ return true;
+ }
+
+ public byte[] GetBytes ()
+ {
+ return ASN1.GetBytes ();
+ }
+
+ public override int GetHashCode ()
+ {
+ // OID should be unique in a collection of extensions
+ return extnOid.GetHashCode ();
+ }
+
+ private void WriteLine (StringBuilder sb, int n, int pos)
+ {
+ byte[] value = extnValue.Value;
+ int p = pos;
+ for (int j=0; j < 8; j++) {
+ if (j < n) {
+ sb.Append (value [p++].ToString ("X2", CultureInfo.InvariantCulture));
+ sb.Append (" ");
+ }
+ else
+ sb.Append (" ");
+ }
+ sb.Append (" ");
+ p = pos;
+ for (int j=0; j < n; j++) {
+ byte b = value [p++];
+ if (b < 0x20)
+ sb.Append (".");
+ else
+ sb.Append (Convert.ToChar (b));
+ }
+ sb.Append (Environment.NewLine);
+ }
+
+ public override string ToString ()
+ {
+ StringBuilder sb = new StringBuilder ();
+ int div = (extnValue.Length >> 3);
+ int rem = (extnValue.Length - (div << 3));
+ int x = 0;
+ for (int i=0; i < div; i++) {
+ WriteLine (sb, 8, x);
+ x += 8;
+ }
+ WriteLine (sb, rem, x);
+ return sb.ToString ();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs
new file mode 100644
index 000000000..c7d5f0046
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X509Extensions.cs
@@ -0,0 +1,195 @@
+//
+// X509Extensions.cs: Handles X.509 extensions.
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// (C) 2004 Novell (http://www.novell.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+namespace Emby.Common.Implementations.Security
+{
+ /*
+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Note: 1..MAX -> There shouldn't be 0 Extensions in the ASN1 structure
+ */
+ public sealed class X509ExtensionCollection : CollectionBase, IEnumerable {
+
+ private bool readOnly;
+
+ public X509ExtensionCollection () : base ()
+ {
+ }
+
+ public X509ExtensionCollection (ASN1 asn1) : this ()
+ {
+ readOnly = true;
+ if (asn1 == null)
+ return;
+ if (asn1.Tag != 0x30)
+ throw new Exception ("Invalid extensions format");
+ for (int i=0; i < asn1.Count; i++) {
+ X509Extension extension = new X509Extension (asn1 [i]);
+ InnerList.Add (extension);
+ }
+ }
+
+ public int Add (X509Extension extension)
+ {
+ if (extension == null)
+ throw new ArgumentNullException ("extension");
+ if (readOnly)
+ throw new NotSupportedException ("Extensions are read only");
+
+ return InnerList.Add (extension);
+ }
+
+ public void AddRange (X509Extension[] extension)
+ {
+ if (extension == null)
+ throw new ArgumentNullException ("extension");
+ if (readOnly)
+ throw new NotSupportedException ("Extensions are read only");
+
+ for (int i = 0; i < extension.Length; i++)
+ InnerList.Add (extension [i]);
+ }
+
+ public void AddRange (X509ExtensionCollection collection)
+ {
+ if (collection == null)
+ throw new ArgumentNullException ("collection");
+ if (readOnly)
+ throw new NotSupportedException ("Extensions are read only");
+
+ for (int i = 0; i < collection.InnerList.Count; i++)
+ InnerList.Add (collection [i]);
+ }
+
+ public bool Contains (X509Extension extension)
+ {
+ return (IndexOf (extension) != -1);
+ }
+
+ public bool Contains (string oid)
+ {
+ return (IndexOf (oid) != -1);
+ }
+
+ public void CopyTo (X509Extension[] extensions, int index)
+ {
+ if (extensions == null)
+ throw new ArgumentNullException ("extensions");
+
+ InnerList.CopyTo (extensions, index);
+ }
+
+ public int IndexOf (X509Extension extension)
+ {
+ if (extension == null)
+ throw new ArgumentNullException ("extension");
+
+ for (int i=0; i < InnerList.Count; i++) {
+ X509Extension ex = (X509Extension) InnerList [i];
+ if (ex.Equals (extension))
+ return i;
+ }
+ return -1;
+ }
+
+ public int IndexOf (string oid)
+ {
+ if (oid == null)
+ throw new ArgumentNullException ("oid");
+
+ for (int i=0; i < InnerList.Count; i++) {
+ X509Extension ex = (X509Extension) InnerList [i];
+ if (ex.Oid == oid)
+ return i;
+ }
+ return -1;
+ }
+
+ public void Insert (int index, X509Extension extension)
+ {
+ if (extension == null)
+ throw new ArgumentNullException ("extension");
+
+ InnerList.Insert (index, extension);
+ }
+
+ public void Remove (X509Extension extension)
+ {
+ if (extension == null)
+ throw new ArgumentNullException ("extension");
+
+ InnerList.Remove (extension);
+ }
+
+ public void Remove (string oid)
+ {
+ if (oid == null)
+ throw new ArgumentNullException ("oid");
+
+ int index = IndexOf (oid);
+ if (index != -1)
+ InnerList.RemoveAt (index);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return InnerList.GetEnumerator ();
+ }
+
+ public X509Extension this [int index] {
+ get { return (X509Extension) InnerList [index]; }
+ }
+
+ public X509Extension this [string oid] {
+ get {
+ int index = IndexOf (oid);
+ if (index == -1)
+ return null;
+ return (X509Extension) InnerList [index];
+ }
+ }
+
+ public byte[] GetBytes ()
+ {
+ if (InnerList.Count < 1)
+ return null;
+ ASN1 sequence = new ASN1 (0x30);
+ for (int i=0; i < InnerList.Count; i++) {
+ X509Extension x = (X509Extension) InnerList [i];
+ sequence.Add (x.ASN1);
+ }
+ return sequence.GetBytes ();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs b/MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs
new file mode 100644
index 000000000..5062bf80a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Cryptography/X520Attributes.cs
@@ -0,0 +1,346 @@
+//
+// X520.cs: X.520 related stuff (attributes, RDN)
+//
+// Author:
+// Sebastien Pouliot <sebastien@ximian.com>
+//
+// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Text;
+
+namespace Emby.Common.Implementations.Security
+{
+
+ // References:
+ // 1. Information technology - Open Systems Interconnection - The Directory: Selected attribute types
+ // http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.520
+ // 2. Internet X.509 Public Key Infrastructure Certificate and CRL Profile
+ // http://www.ietf.org/rfc/rfc3280.txt
+ // 3. A Summary of the X.500(96) User Schema for use with LDAPv3
+ // http://www.faqs.org/rfcs/rfc2256.html
+ // 4. RFC 2247 - Using Domains in LDAP/X.500 Distinguished Names
+ // http://www.faqs.org/rfcs/rfc2247.html
+
+ /*
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue
+ * }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ */
+ public class X520 {
+
+ public abstract class AttributeTypeAndValue {
+ private string oid;
+ private string attrValue;
+ private int upperBound;
+ private byte encoding;
+
+ protected AttributeTypeAndValue (string oid, int upperBound)
+ {
+ this.oid = oid;
+ this.upperBound = upperBound;
+ this.encoding = 0xFF;
+ }
+
+ protected AttributeTypeAndValue (string oid, int upperBound, byte encoding)
+ {
+ this.oid = oid;
+ this.upperBound = upperBound;
+ this.encoding = encoding;
+ }
+
+ public string Value {
+ get { return attrValue; }
+ set {
+ if ((attrValue != null) && (attrValue.Length > upperBound)) {
+ string msg = ("Value length bigger than upperbound ({0}).");
+ throw new FormatException (String.Format (msg, upperBound));
+ }
+ attrValue = value;
+ }
+ }
+
+ public ASN1 ASN1 {
+ get { return GetASN1 (); }
+ }
+
+ internal ASN1 GetASN1 (byte encoding)
+ {
+ byte encode = encoding;
+ if (encode == 0xFF)
+ encode = SelectBestEncoding ();
+
+ ASN1 asn1 = new ASN1 (0x30);
+ asn1.Add (ASN1Convert.FromOid (oid));
+ switch (encode) {
+ case 0x13:
+ // PRINTABLESTRING
+ asn1.Add (new ASN1 (0x13, Encoding.ASCII.GetBytes (attrValue)));
+ break;
+ case 0x16:
+ // IA5STRING
+ asn1.Add (new ASN1 (0x16, Encoding.ASCII.GetBytes (attrValue)));
+ break;
+ case 0x1E:
+ // BMPSTRING
+ asn1.Add (new ASN1 (0x1E, Encoding.BigEndianUnicode.GetBytes (attrValue)));
+ break;
+ }
+ return asn1;
+ }
+
+ internal ASN1 GetASN1 ()
+ {
+ return GetASN1 (encoding);
+ }
+
+ public byte[] GetBytes (byte encoding)
+ {
+ return GetASN1 (encoding) .GetBytes ();
+ }
+
+ public byte[] GetBytes ()
+ {
+ return GetASN1 () .GetBytes ();
+ }
+
+ private byte SelectBestEncoding ()
+ {
+ foreach (char c in attrValue) {
+ switch (c) {
+ case '@':
+ case '_':
+ return 0x1E; // BMPSTRING
+ default:
+ if (c > 127)
+ return 0x1E; // BMPSTRING
+ break;
+ }
+ }
+ return 0x13; // PRINTABLESTRING
+ }
+ }
+
+ public class Name : AttributeTypeAndValue {
+
+ public Name () : base ("2.5.4.41", 32768)
+ {
+ }
+ }
+
+ public class CommonName : AttributeTypeAndValue {
+
+ public CommonName () : base ("2.5.4.3", 64)
+ {
+ }
+ }
+
+ // RFC2256, Section 5.6
+ public class SerialNumber : AttributeTypeAndValue {
+
+ // max length 64 bytes, Printable String only
+ public SerialNumber ()
+ : base ("2.5.4.5", 64, 0x13)
+ {
+ }
+ }
+
+ public class LocalityName : AttributeTypeAndValue {
+
+ public LocalityName () : base ("2.5.4.7", 128)
+ {
+ }
+ }
+
+ public class StateOrProvinceName : AttributeTypeAndValue {
+
+ public StateOrProvinceName () : base ("2.5.4.8", 128)
+ {
+ }
+ }
+
+ public class OrganizationName : AttributeTypeAndValue {
+
+ public OrganizationName () : base ("2.5.4.10", 64)
+ {
+ }
+ }
+
+ public class OrganizationalUnitName : AttributeTypeAndValue {
+
+ public OrganizationalUnitName () : base ("2.5.4.11", 64)
+ {
+ }
+ }
+
+ // NOTE: Not part of RFC2253
+ public class EmailAddress : AttributeTypeAndValue {
+
+ public EmailAddress () : base ("1.2.840.113549.1.9.1", 128, 0x16)
+ {
+ }
+ }
+
+ // RFC2247, Section 4
+ public class DomainComponent : AttributeTypeAndValue {
+
+ // no maximum length defined
+ public DomainComponent ()
+ : base ("0.9.2342.19200300.100.1.25", Int32.MaxValue, 0x16)
+ {
+ }
+ }
+
+ // RFC1274, Section 9.3.1
+ public class UserId : AttributeTypeAndValue {
+
+ public UserId ()
+ : base ("0.9.2342.19200300.100.1.1", 256)
+ {
+ }
+ }
+
+ public class Oid : AttributeTypeAndValue {
+
+ public Oid (string oid)
+ : base (oid, Int32.MaxValue)
+ {
+ }
+ }
+
+ /* -- Naming attributes of type X520Title
+ * id-at-title AttributeType ::= { id-at 12 }
+ *
+ * X520Title ::= CHOICE {
+ * teletexString TeletexString (SIZE (1..ub-title)),
+ * printableString PrintableString (SIZE (1..ub-title)),
+ * universalString UniversalString (SIZE (1..ub-title)),
+ * utf8String UTF8String (SIZE (1..ub-title)),
+ * bmpString BMPString (SIZE (1..ub-title))
+ * }
+ */
+ public class Title : AttributeTypeAndValue {
+
+ public Title () : base ("2.5.4.12", 64)
+ {
+ }
+ }
+
+ public class CountryName : AttributeTypeAndValue {
+
+ // (0x13) PRINTABLESTRING
+ public CountryName () : base ("2.5.4.6", 2, 0x13)
+ {
+ }
+ }
+
+ public class DnQualifier : AttributeTypeAndValue {
+
+ // (0x13) PRINTABLESTRING
+ public DnQualifier () : base ("2.5.4.46", 2, 0x13)
+ {
+ }
+ }
+
+ public class Surname : AttributeTypeAndValue {
+
+ public Surname () : base ("2.5.4.4", 32768)
+ {
+ }
+ }
+
+ public class GivenName : AttributeTypeAndValue {
+
+ public GivenName () : base ("2.5.4.42", 16)
+ {
+ }
+ }
+
+ public class Initial : AttributeTypeAndValue {
+
+ public Initial () : base ("2.5.4.43", 5)
+ {
+ }
+ }
+
+ }
+
+ /* From RFC3280
+ * -- specifications of Upper Bounds MUST be regarded as mandatory
+ * -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
+ *
+ * -- Upper Bounds
+ *
+ * ub-name INTEGER ::= 32768
+ * ub-common-name INTEGER ::= 64
+ * ub-locality-name INTEGER ::= 128
+ * ub-state-name INTEGER ::= 128
+ * ub-organization-name INTEGER ::= 64
+ * ub-organizational-unit-name INTEGER ::= 64
+ * ub-title INTEGER ::= 64
+ * ub-serial-number INTEGER ::= 64
+ * ub-match INTEGER ::= 128
+ * ub-emailaddress-length INTEGER ::= 128
+ * ub-common-name-length INTEGER ::= 64
+ * ub-country-name-alpha-length INTEGER ::= 2
+ * ub-country-name-numeric-length INTEGER ::= 3
+ * ub-domain-defined-attributes INTEGER ::= 4
+ * ub-domain-defined-attribute-type-length INTEGER ::= 8
+ * ub-domain-defined-attribute-value-length INTEGER ::= 128
+ * ub-domain-name-length INTEGER ::= 16
+ * ub-extension-attributes INTEGER ::= 256
+ * ub-e163-4-number-length INTEGER ::= 15
+ * ub-e163-4-sub-address-length INTEGER ::= 40
+ * ub-generation-qualifier-length INTEGER ::= 3
+ * ub-given-name-length INTEGER ::= 16
+ * ub-initials-length INTEGER ::= 5
+ * ub-integer-options INTEGER ::= 256
+ * ub-numeric-user-id-length INTEGER ::= 32
+ * ub-organization-name-length INTEGER ::= 64
+ * ub-organizational-unit-name-length INTEGER ::= 32
+ * ub-organizational-units INTEGER ::= 4
+ * ub-pds-name-length INTEGER ::= 16
+ * ub-pds-parameter-length INTEGER ::= 30
+ * ub-pds-physical-address-lines INTEGER ::= 6
+ * ub-postal-code-length INTEGER ::= 16
+ * ub-pseudonym INTEGER ::= 128
+ * ub-surname-length INTEGER ::= 40
+ * ub-terminal-id-length INTEGER ::= 24
+ * ub-unformatted-address-length INTEGER ::= 180
+ * ub-x121-address-length INTEGER ::= 16
+ *
+ * -- Note - upper bounds on string types, such as TeletexString, are
+ * -- measured in characters. Excepting PrintableString or IA5String, a
+ * -- significantly greater number of octets will be required to hold
+ * -- such a value. As a minimum, 16 octets, or twice the specified
+ * -- upper bound, whichever is the larger, should be allowed for
+ * -- TeletexString. For UTF8String or UniversalString at least four
+ * -- times the upper bound should be allowed.
+ */
+}
diff --git a/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs b/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs
deleted file mode 100644
index dbfd6f4e8..000000000
--- a/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Linq;
-using MediaBrowser.Common.Threading;
-
-namespace MediaBrowser.Server.Startup.Common.EntryPoints
-{
- public class KeepServerAwake : IServerEntryPoint
- {
- private readonly ISessionManager _sessionManager;
- private readonly ILogger _logger;
- private PeriodicTimer _timer;
- private readonly IServerApplicationHost _appHost;
-
- public KeepServerAwake(ISessionManager sessionManager, ILogger logger, IServerApplicationHost appHost)
- {
- _sessionManager = sessionManager;
- _logger = logger;
- _appHost = appHost;
- }
-
- public void Run()
- {
- _timer = new PeriodicTimer(obj =>
- {
- var now = DateTime.UtcNow;
- var nativeApp = ((ApplicationHost)_appHost).NativeApp;
-
- try
- {
- if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15))
- {
- nativeApp.PreventSystemStandby();
- }
- else
- {
- nativeApp.AllowSystemStandby();
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error resetting system standby timer", ex);
- }
-
- }, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
- }
-
- public void Dispose()
- {
- if (_timer != null)
- {
- _timer.Dispose();
- _timer = null;
- }
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs b/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs
deleted file mode 100644
index f9d173c59..000000000
--- a/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Startup.Common.Browser;
-
-namespace MediaBrowser.Server.Startup.Common.EntryPoints
-{
- /// <summary>
- /// Class StartupWizard
- /// </summary>
- public class StartupWizard : IServerEntryPoint
- {
- /// <summary>
- /// The _app host
- /// </summary>
- private readonly IServerApplicationHost _appHost;
- /// <summary>
- /// The _user manager
- /// </summary>
- private readonly ILogger _logger;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="StartupWizard" /> class.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- /// <param name="logger">The logger.</param>
- public StartupWizard(IServerApplicationHost appHost, ILogger logger)
- {
- _appHost = appHost;
- _logger = logger;
- }
-
- /// <summary>
- /// Runs this instance.
- /// </summary>
- public void Run()
- {
- if (_appHost.IsFirstRun)
- {
- LaunchStartupWizard();
- }
- }
-
- /// <summary>
- /// Launches the startup wizard.
- /// </summary>
- private void LaunchStartupWizard()
- {
- BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost);
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs
deleted file mode 100644
index d33b12a9a..000000000
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInfo.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace MediaBrowser.Server.Startup.Common.FFMpeg
-{
- /// <summary>
- /// Class FFMpegInfo
- /// </summary>
- public class FFMpegInfo
- {
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- public string EncoderPath { get; set; }
- /// <summary>
- /// Gets or sets the probe path.
- /// </summary>
- /// <value>The probe path.</value>
- public string ProbePath { get; set; }
- /// <summary>
- /// Gets or sets the version.
- /// </summary>
- /// <value>The version.</value>
- public string Version { get; set; }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs
deleted file mode 100644
index a2a44f805..000000000
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-
-namespace MediaBrowser.Server.Startup.Common.FFMpeg
-{
- public class FFMpegInstallInfo
- {
- public string Version { get; set; }
- public string FFMpegFilename { get; set; }
- public string FFProbeFilename { get; set; }
- public string ArchiveType { get; set; }
- public string[] DownloadUrls { get; set; }
-
- public FFMpegInstallInfo()
- {
- DownloadUrls = new string[] { };
- Version = "Path";
- FFMpegFilename = "ffmpeg";
- FFProbeFilename = "ffprobe";
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs
deleted file mode 100644
index 68e2a4927..000000000
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs
+++ /dev/null
@@ -1,248 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-using Mono.Unix.Native;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using CommonIO;
-
-namespace MediaBrowser.Server.Startup.Common.FFMpeg
-{
- public class FFMpegLoader
- {
- private readonly IHttpClient _httpClient;
- private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
- private readonly IZipClient _zipClient;
- private readonly IFileSystem _fileSystem;
- private readonly NativeEnvironment _environment;
- private readonly FFMpegInstallInfo _ffmpegInstallInfo;
-
- public FFMpegLoader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient, IFileSystem fileSystem, NativeEnvironment environment, FFMpegInstallInfo ffmpegInstallInfo)
- {
- _logger = logger;
- _appPaths = appPaths;
- _httpClient = httpClient;
- _zipClient = zipClient;
- _fileSystem = fileSystem;
- _environment = environment;
- _ffmpegInstallInfo = ffmpegInstallInfo;
- }
-
- public async Task<FFMpegInfo> GetFFMpegInfo(NativeEnvironment environment, StartupOptions options, IProgress<double> progress)
- {
- var customffMpegPath = options.GetOption("-ffmpeg");
- var customffProbePath = options.GetOption("-ffprobe");
-
- if (!string.IsNullOrWhiteSpace(customffMpegPath) && !string.IsNullOrWhiteSpace(customffProbePath))
- {
- return new FFMpegInfo
- {
- ProbePath = customffProbePath,
- EncoderPath = customffMpegPath,
- Version = "external"
- };
- }
-
- var downloadInfo = _ffmpegInstallInfo;
-
- var version = downloadInfo.Version;
-
- if (string.Equals(version, "path", StringComparison.OrdinalIgnoreCase))
- {
- return new FFMpegInfo
- {
- ProbePath = downloadInfo.FFProbeFilename,
- EncoderPath = downloadInfo.FFMpegFilename,
- Version = version
- };
- }
-
- if (string.Equals(version, "0", StringComparison.OrdinalIgnoreCase))
- {
- return new FFMpegInfo();
- }
-
- var rootEncoderPath = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
- var versionedDirectoryPath = Path.Combine(rootEncoderPath, version);
-
- var info = new FFMpegInfo
- {
- ProbePath = Path.Combine(versionedDirectoryPath, downloadInfo.FFProbeFilename),
- EncoderPath = Path.Combine(versionedDirectoryPath, downloadInfo.FFMpegFilename),
- Version = version
- };
-
- _fileSystem.CreateDirectory(versionedDirectoryPath);
-
- var excludeFromDeletions = new List<string> { versionedDirectoryPath };
-
- if (!_fileSystem.FileExists(info.ProbePath) || !_fileSystem.FileExists(info.EncoderPath))
- {
- // ffmpeg not present. See if there's an older version we can start with
- var existingVersion = GetExistingVersion(info, rootEncoderPath);
-
- // No older version. Need to download and block until complete
- if (existingVersion == null)
- {
- var success = await DownloadFFMpeg(downloadInfo, versionedDirectoryPath, progress).ConfigureAwait(false);
- if (!success)
- {
- return new FFMpegInfo();
- }
- }
- else
- {
- info = existingVersion;
- versionedDirectoryPath = Path.GetDirectoryName(info.EncoderPath);
- excludeFromDeletions.Add(versionedDirectoryPath);
- }
- }
-
- // Allow just one of these to be overridden, if desired.
- if (!string.IsNullOrWhiteSpace(customffMpegPath))
- {
- info.EncoderPath = customffMpegPath;
- }
- if (!string.IsNullOrWhiteSpace(customffProbePath))
- {
- info.EncoderPath = customffProbePath;
- }
-
- return info;
- }
-
- private FFMpegInfo GetExistingVersion(FFMpegInfo info, string rootEncoderPath)
- {
- var encoderFilename = Path.GetFileName(info.EncoderPath);
- var probeFilename = Path.GetFileName(info.ProbePath);
-
- foreach (var directory in Directory.EnumerateDirectories(rootEncoderPath, "*", SearchOption.TopDirectoryOnly)
- .ToList())
- {
- var allFiles = Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories).ToList();
-
- var encoder = allFiles.FirstOrDefault(i => string.Equals(Path.GetFileName(i), encoderFilename, StringComparison.OrdinalIgnoreCase));
- var probe = allFiles.FirstOrDefault(i => string.Equals(Path.GetFileName(i), probeFilename, StringComparison.OrdinalIgnoreCase));
-
- if (!string.IsNullOrWhiteSpace(encoder) &&
- !string.IsNullOrWhiteSpace(probe))
- {
- return new FFMpegInfo
- {
- EncoderPath = encoder,
- ProbePath = probe,
- Version = Path.GetFileName(Path.GetDirectoryName(probe))
- };
- }
- }
-
- return null;
- }
-
- private async Task<bool> DownloadFFMpeg(FFMpegInstallInfo downloadinfo, string directory, IProgress<double> progress)
- {
- foreach (var url in downloadinfo.DownloadUrls)
- {
- progress.Report(0);
-
- try
- {
- var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
- {
- Url = url,
- CancellationToken = CancellationToken.None,
- Progress = progress
-
- }).ConfigureAwait(false);
-
- ExtractFFMpeg(downloadinfo, tempFile, directory);
- return true;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error downloading {0}", ex, url);
- }
- }
- return false;
- }
-
- private void ExtractFFMpeg(FFMpegInstallInfo downloadinfo, string tempFile, string targetFolder)
- {
- _logger.Info("Extracting ffmpeg from {0}", tempFile);
-
- var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString());
-
- _fileSystem.CreateDirectory(tempFolder);
-
- try
- {
- ExtractArchive(downloadinfo, tempFile, tempFolder);
-
- var files = Directory.EnumerateFiles(tempFolder, "*", SearchOption.AllDirectories)
- .ToList();
-
- foreach (var file in files.Where(i =>
- {
- var filename = Path.GetFileName(i);
-
- return
- string.Equals(filename, downloadinfo.FFProbeFilename, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(filename, downloadinfo.FFMpegFilename, StringComparison.OrdinalIgnoreCase);
- }))
- {
- var targetFile = Path.Combine(targetFolder, Path.GetFileName(file));
- _fileSystem.CopyFile(file, targetFile, true);
- SetFilePermissions(targetFile);
- }
- }
- finally
- {
- DeleteFile(tempFile);
- }
- }
-
- private void SetFilePermissions(string path)
- {
- // Linux: File permission to 666, and user's execute bit
- if (_environment.OperatingSystem == OperatingSystem.Bsd || _environment.OperatingSystem == OperatingSystem.Linux || _environment.OperatingSystem == OperatingSystem.Osx)
- {
- _logger.Info("Syscall.chmod {0} FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH", path);
-
- Syscall.chmod(path, FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH);
- }
- }
-
- private void ExtractArchive(FFMpegInstallInfo downloadinfo, string archivePath, string targetPath)
- {
- _logger.Info("Extracting {0} to {1}", archivePath, targetPath);
-
- if (string.Equals(downloadinfo.ArchiveType, "7z", StringComparison.OrdinalIgnoreCase))
- {
- _zipClient.ExtractAllFrom7z(archivePath, targetPath, true);
- }
- else if (string.Equals(downloadinfo.ArchiveType, "gz", StringComparison.OrdinalIgnoreCase))
- {
- _zipClient.ExtractAllFromTar(archivePath, targetPath, true);
- }
- }
-
- private void DeleteFile(string path)
- {
- try
- {
- _fileSystem.DeleteFile(path);
- }
- catch (IOException ex)
- {
- _logger.ErrorException("Error deleting temp file {0}", ex, path);
- }
- }
-
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs
deleted file mode 100644
index c56bb9b4b..000000000
--- a/MediaBrowser.Server.Startup.Common/INativeApp.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.Logging;
-using System.Collections.Generic;
-using System.Reflection;
-using MediaBrowser.Server.Implementations.Persistence;
-using MediaBrowser.Server.Startup.Common.FFMpeg;
-
-namespace MediaBrowser.Server.Startup.Common
-{
- public interface INativeApp
- {
- /// <summary>
- /// Gets the assemblies with parts.
- /// </summary>
- /// <returns>List&lt;Assembly&gt;.</returns>
- List<Assembly> GetAssembliesWithParts();
-
- /// <summary>
- /// Authorizes the server.
- /// </summary>
- /// <param name="udpPort">The UDP port.</param>
- /// <param name="httpServerPort">The HTTP server port.</param>
- /// <param name="httpsServerPort">The HTTPS server port.</param>
- /// <param name="tempDirectory">The temporary directory.</param>
- void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory);
-
- /// <summary>
- /// Gets the environment.
- /// </summary>
- /// <value>The environment.</value>
- NativeEnvironment Environment { get; }
-
- /// <summary>
- /// Gets a value indicating whether [supports running as service].
- /// </summary>
- /// <value><c>true</c> if [supports running as service]; otherwise, <c>false</c>.</value>
- bool SupportsRunningAsService { get; }
-
- /// <summary>
- /// Gets a value indicating whether this instance is running as service.
- /// </summary>
- /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
- bool IsRunningAsService { get; }
-
- /// <summary>
- /// Gets a value indicating whether this instance can self restart.
- /// </summary>
- /// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
- bool CanSelfRestart { get; }
-
- /// <summary>
- /// Gets a value indicating whether [supports autorun at startup].
- /// </summary>
- /// <value><c>true</c> if [supports autorun at startup]; otherwise, <c>false</c>.</value>
- bool SupportsAutoRunAtStartup { get; }
-
- /// <summary>
- /// Gets a value indicating whether [supports library monitor].
- /// </summary>
- /// <value><c>true</c> if [supports library monitor]; otherwise, <c>false</c>.</value>
- bool SupportsLibraryMonitor { get; }
-
- /// <summary>
- /// Gets a value indicating whether this instance can self update.
- /// </summary>
- /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
- bool CanSelfUpdate { get; }
-
- /// <summary>
- /// Shutdowns this instance.
- /// </summary>
- void Shutdown();
-
- /// <summary>
- /// Restarts this instance.
- /// </summary>
- void Restart(StartupOptions startupOptions);
-
- /// <summary>
- /// Configures the automatic run.
- /// </summary>
- /// <param name="autorun">if set to <c>true</c> [autorun].</param>
- void ConfigureAutoRun(bool autorun);
-
- /// <summary>
- /// Gets the network manager.
- /// </summary>
- /// <returns>INetworkManager.</returns>
- INetworkManager CreateNetworkManager(ILogger logger);
-
- /// <summary>
- /// Prevents the system stand by.
- /// </summary>
- void PreventSystemStandby();
-
- void AllowSystemStandby();
-
- FFMpegInstallInfo GetFfmpegInstallInfo();
-
- void LaunchUrl(string url);
-
- IDbConnector GetDbConnector();
-
- void EnableLoopback(string appName);
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs b/MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs
new file mode 100644
index 000000000..3ca0f4db5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/IO/MemoryStreamProvider.cs
@@ -0,0 +1,56 @@
+using System.IO;
+using MediaBrowser.Model.IO;
+using Microsoft.IO;
+
+namespace MediaBrowser.Server.Startup.Common.IO
+{
+ public class RecyclableMemoryStreamProvider : IMemoryStreamFactory
+ {
+ readonly RecyclableMemoryStreamManager _manager = new RecyclableMemoryStreamManager();
+
+ public MemoryStream CreateNew()
+ {
+ return _manager.GetStream();
+ }
+
+ public MemoryStream CreateNew(int capacity)
+ {
+ return _manager.GetStream("RecyclableMemoryStream", capacity);
+ }
+
+ public MemoryStream CreateNew(byte[] buffer)
+ {
+ return _manager.GetStream("RecyclableMemoryStream", buffer, 0, buffer.Length);
+ }
+
+ public bool TryGetBuffer(MemoryStream stream, out byte[] buffer)
+ {
+ buffer = stream.GetBuffer();
+ return true;
+ }
+ }
+
+ public class MemoryStreamProvider : IMemoryStreamFactory
+ {
+ public MemoryStream CreateNew()
+ {
+ return new MemoryStream();
+ }
+
+ public MemoryStream CreateNew(int capacity)
+ {
+ return new MemoryStream(capacity);
+ }
+
+ public MemoryStream CreateNew(byte[] buffer)
+ {
+ return new MemoryStream(buffer);
+ }
+
+ public bool TryGetBuffer(MemoryStream stream, out byte[] buffer)
+ {
+ buffer = stream.GetBuffer();
+ return true;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs b/MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs
new file mode 100644
index 000000000..ddbde2f66
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/ImageEncoderHelper.cs
@@ -0,0 +1,48 @@
+using System;
+using Emby.Drawing;
+using Emby.Drawing.Net;
+using Emby.Drawing.ImageMagick;
+using Emby.Server.Core;
+using Emby.Server.Implementations;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+
+namespace MediaBrowser.Server.Startup.Common
+{
+ public class ImageEncoderHelper
+ {
+ public static IImageEncoder GetImageEncoder(ILogger logger,
+ ILogManager logManager,
+ IFileSystem fileSystem,
+ StartupOptions startupOptions,
+ Func<IHttpClient> httpClient,
+ IApplicationPaths appPaths)
+ {
+ if (!startupOptions.ContainsOption("-enablegdi"))
+ {
+ try
+ {
+ return new ImageMagickEncoder(logManager.GetLogger("ImageMagick"), appPaths, httpClient, fileSystem);
+ }
+ catch
+ {
+ logger.Error("Error loading ImageMagick. Will revert to GDI.");
+ }
+ }
+
+ try
+ {
+ return new GDIImageEncoder(fileSystem, logManager.GetLogger("GDI"));
+ }
+ catch
+ {
+ logger.Error("Error loading GDI. Will revert to NullImageEncoder.");
+ }
+
+ return new NullImageEncoder();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs
new file mode 100644
index 000000000..fdeae25b0
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ChannelScan.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using IniParser;
+using IniParser.Model;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Model.LiveTv;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
+{
+ public class ChannelScan
+ {
+ private readonly ILogger _logger;
+
+ public ChannelScan(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public async Task<List<ChannelInfo>> Scan(TunerHostInfo info, CancellationToken cancellationToken)
+ {
+ var ini = info.SourceA.Split('|')[1];
+ var resource = GetType().Assembly.GetManifestResourceNames().FirstOrDefault(i => i.EndsWith(ini, StringComparison.OrdinalIgnoreCase));
+
+ _logger.Info("Opening ini file {0}", resource);
+ var list = new List<ChannelInfo>();
+
+ using (var stream = GetType().Assembly.GetManifestResourceStream(resource))
+ {
+ using (var reader = new StreamReader(stream))
+ {
+ var parser = new StreamIniDataParser();
+ var data = parser.ReadData(reader);
+
+ var count = GetInt(data, "DVB", "0", 0);
+
+ _logger.Info("DVB Count: {0}", count);
+
+ var index = 1;
+ var source = "1";
+
+ while (index <= count)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ using (var rtspSession = new RtspSession(info.Url, _logger))
+ {
+ float percent = count == 0 ? 0 : (float)(index) / count;
+ percent = Math.Max(percent * 100, 100);
+
+ //SetControlPropertyThreadSafe(pgbSearchResult, "Value", (int)percent);
+ var strArray = data["DVB"][index.ToString(CultureInfo.InvariantCulture)].Split(',');
+
+ string tuning;
+ if (strArray[4] == "S2")
+ {
+ tuning = string.Format("src={0}&freq={1}&pol={2}&sr={3}&fec={4}&msys=dvbs2&mtype={5}&plts=on&ro=0.35&pids=0,16,17,18,20", source, strArray[0], strArray[1].ToLower(), strArray[2].ToLower(), strArray[3], strArray[5].ToLower());
+ }
+ else
+ {
+ tuning = string.Format("src={0}&freq={1}&pol={2}&sr={3}&fec={4}&msys=dvbs&mtype={5}&pids=0,16,17,18,20", source, strArray[0], strArray[1].ToLower(), strArray[2], strArray[3], strArray[5].ToLower());
+ }
+
+ rtspSession.Setup(tuning, "unicast");
+
+ rtspSession.Play(string.Empty);
+
+ int signallevel;
+ int signalQuality;
+ rtspSession.Describe(out signallevel, out signalQuality);
+
+ await Task.Delay(500).ConfigureAwait(false);
+ index++;
+ }
+ }
+ }
+ }
+
+ return list;
+ }
+
+ private int GetInt(IniData data, string s1, string s2, int defaultValue)
+ {
+ var value = data[s1][s2];
+ int numericValue;
+ if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out numericValue))
+ {
+ return numericValue;
+ }
+
+ return defaultValue;
+ }
+ }
+
+ public class SatChannel
+ {
+ // TODO: Add properties
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs
new file mode 100644
index 000000000..dddd77179
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/ReportBlock.cs
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ public class ReportBlock
+ {
+ /// <summary>
+ /// Get the length of the block.
+ /// </summary>
+ public int BlockLength { get { return (24); } }
+ /// <summary>
+ /// Get the synchronization source.
+ /// </summary>
+ public string SynchronizationSource { get; private set; }
+ /// <summary>
+ /// Get the fraction lost.
+ /// </summary>
+ public int FractionLost { get; private set; }
+ /// <summary>
+ /// Get the cumulative packets lost.
+ /// </summary>
+ public int CumulativePacketsLost { get; private set; }
+ /// <summary>
+ /// Get the highest number received.
+ /// </summary>
+ public int HighestNumberReceived { get; private set; }
+ /// <summary>
+ /// Get the inter arrival jitter.
+ /// </summary>
+ public int InterArrivalJitter { get; private set; }
+ /// <summary>
+ /// Get the timestamp of the last report.
+ /// </summary>
+ public int LastReportTimeStamp { get; private set; }
+ /// <summary>
+ /// Get the delay since the last report.
+ /// </summary>
+ public int DelaySinceLastReport { get; private set; }
+
+ /// <summary>
+ /// Initialize a new instance of the ReportBlock class.
+ /// </summary>
+ public ReportBlock() { }
+
+ /// <summary>
+ /// Unpack the data in a packet.
+ /// </summary>
+ /// <param name="buffer">The buffer containing the packet.</param>
+ /// <param name="offset">The offset to the first byte of the packet within the buffer.</param>
+ /// <returns>An ErrorSpec instance if an error occurs; null otherwise.</returns>
+ public void Process(byte[] buffer, int offset)
+ {
+ SynchronizationSource = Utils.ConvertBytesToString(buffer, offset, 4);
+ FractionLost = buffer[offset + 4];
+ CumulativePacketsLost = Utils.Convert3BytesToInt(buffer, offset + 5);
+ HighestNumberReceived = Utils.Convert4BytesToInt(buffer, offset + 8);
+ InterArrivalJitter = Utils.Convert4BytesToInt(buffer, offset + 12);
+ LastReportTimeStamp = Utils.Convert4BytesToInt(buffer, offset + 16);
+ DelaySinceLastReport = Utils.Convert4BytesToInt(buffer, offset + 20);
+
+
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs
new file mode 100644
index 000000000..990b6dd94
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpAppPacket.cs
@@ -0,0 +1,68 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ class RtcpAppPacket : RtcpPacket
+ {
+ /// <summary>
+ /// Get the synchronization source.
+ /// </summary>
+ public int SynchronizationSource { get; private set; }
+ /// <summary>
+ /// Get the name.
+ /// </summary>
+ public string Name { get; private set; }
+ /// <summary>
+ /// Get the identity.
+ /// </summary>
+ public int Identity { get; private set; }
+ /// <summary>
+ /// Get the variable data portion.
+ /// </summary>
+ public string Data { get; private set; }
+
+ public override void Parse(byte[] buffer, int offset)
+ {
+ base.Parse(buffer, offset);
+ SynchronizationSource = Utils.Convert4BytesToInt(buffer, offset + 4);
+ Name = Utils.ConvertBytesToString(buffer, offset + 8, 4);
+ Identity = Utils.Convert2BytesToInt(buffer, offset + 12);
+
+ int dataLength = Utils.Convert2BytesToInt(buffer, offset + 14);
+ if (dataLength != 0)
+ Data = Utils.ConvertBytesToString(buffer, offset + 16, dataLength);
+ }
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("Application Specific.\n");
+ sb.AppendFormat("Version : {0} .\n", Version);
+ sb.AppendFormat("Padding : {0} .\n", Padding);
+ sb.AppendFormat("Report Count : {0} .\n", ReportCount);
+ sb.AppendFormat("PacketType: {0} .\n", Type);
+ sb.AppendFormat("Length : {0} .\n", Length);
+ sb.AppendFormat("SynchronizationSource : {0} .\n", SynchronizationSource);
+ sb.AppendFormat("Name : {0} .\n", Name);
+ sb.AppendFormat("Identity : {0} .\n", Identity);
+ sb.AppendFormat("Data : {0} .\n", Data);
+ sb.AppendFormat(".\n");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs
new file mode 100644
index 000000000..c79ea31a8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpByePacket.cs
@@ -0,0 +1,59 @@
+using System.Collections.ObjectModel;
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ public class RtcpByePacket :RtcpPacket
+ {
+ public Collection<string> SynchronizationSources { get; private set; }
+ public string ReasonForLeaving { get; private set; }
+ public override void Parse(byte[] buffer, int offset)
+ {
+ base.Parse(buffer, offset);
+ SynchronizationSources = new Collection<string>();
+ int index = 4;
+
+ while (SynchronizationSources.Count < ReportCount)
+ {
+ SynchronizationSources.Add(Utils.ConvertBytesToString(buffer, offset + index, 4));
+ index += 4;
+ }
+
+ if (index < Length)
+ {
+ int reasonLength = buffer[offset + index];
+ ReasonForLeaving = Utils.ConvertBytesToString(buffer, offset + index + 1, reasonLength);
+ }
+ }
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("ByeBye .\n");
+ sb.AppendFormat("Version : {0} .\n", Version);
+ sb.AppendFormat("Padding : {0} .\n", Padding);
+ sb.AppendFormat("Report Count : {0} .\n", ReportCount);
+ sb.AppendFormat("PacketType: {0} .\n", Type);
+ sb.AppendFormat("Length : {0} .\n", Length);
+ sb.AppendFormat("SynchronizationSources : {0} .\n", SynchronizationSources);
+ sb.AppendFormat("ReasonForLeaving : {0} .\n", ReasonForLeaving);
+ sb.AppendFormat(".\n");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs
new file mode 100644
index 000000000..2c54f0665
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpListener.cs
@@ -0,0 +1,203 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using MediaBrowser.Model.Logging;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ public class RtcpListener
+ {
+ private readonly ILogger _logger;
+ private Thread _rtcpListenerThread;
+ private AutoResetEvent _rtcpListenerThreadStopEvent = null;
+ private UdpClient _udpClient;
+ private IPEndPoint _multicastEndPoint;
+ private IPEndPoint _serverEndPoint;
+ private TransmissionMode _transmissionMode;
+
+ public RtcpListener(String address, int port, TransmissionMode mode,ILogger logger)
+ {
+ _logger = logger;
+ _transmissionMode = mode;
+ switch (mode)
+ {
+ case TransmissionMode.Unicast:
+ _udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(address), port));
+ _serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ break;
+ case TransmissionMode.Multicast:
+ _multicastEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
+ _serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ _udpClient = new UdpClient();
+ _udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
+ _udpClient.ExclusiveAddressUse = false;
+ _udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
+ _udpClient.JoinMulticastGroup(_multicastEndPoint.Address);
+ break;
+ }
+ //StartRtcpListenerThread();
+ }
+
+ public void StartRtcpListenerThread()
+ {
+ // Kill the existing thread if it is in "zombie" state.
+ if (_rtcpListenerThread != null && !_rtcpListenerThread.IsAlive)
+ {
+ StopRtcpListenerThread();
+ }
+
+ if (_rtcpListenerThread == null)
+ {
+ _logger.Info("SAT>IP : starting new RTCP listener thread");
+ _rtcpListenerThreadStopEvent = new AutoResetEvent(false);
+ _rtcpListenerThread = new Thread(new ThreadStart(RtcpListenerThread));
+ _rtcpListenerThread.Name = string.Format("SAT>IP tuner RTCP listener");
+ _rtcpListenerThread.IsBackground = true;
+ _rtcpListenerThread.Priority = ThreadPriority.Lowest;
+ _rtcpListenerThread.Start();
+ }
+ }
+
+ public void StopRtcpListenerThread()
+ {
+ if (_rtcpListenerThread != null)
+ {
+ if (!_rtcpListenerThread.IsAlive)
+ {
+ _logger.Info("SAT>IP : aborting old RTCP listener thread");
+ _rtcpListenerThread.Abort();
+ }
+ else
+ {
+ _rtcpListenerThreadStopEvent.Set();
+ if (!_rtcpListenerThread.Join(400 * 2))
+ {
+ _logger.Info("SAT>IP : failed to join RTCP listener thread, aborting thread");
+ _rtcpListenerThread.Abort();
+ }
+ }
+ _rtcpListenerThread = null;
+ if (_rtcpListenerThreadStopEvent != null)
+ {
+ _rtcpListenerThreadStopEvent.Close();
+ _rtcpListenerThreadStopEvent = null;
+ }
+ }
+ }
+
+ private void RtcpListenerThread()
+ {
+ try
+ {
+ bool receivedGoodBye = false;
+ try
+ {
+ _udpClient.Client.ReceiveTimeout = 400;
+ IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ while (!receivedGoodBye && !_rtcpListenerThreadStopEvent.WaitOne(1))
+ {
+ byte[] packets = _udpClient.Receive(ref serverEndPoint);
+ if (packets == null)
+ {
+ continue;
+ }
+
+ int offset = 0;
+ while (offset < packets.Length)
+ {
+ switch (packets[offset + 1])
+ {
+ case 200: //sr
+ var sr = new RtcpSenderReportPacket();
+ sr.Parse(packets, offset);
+ offset += sr.Length;
+ break;
+ case 201: //rr
+ var rr = new RtcpReceiverReportPacket();
+ rr.Parse(packets, offset);
+ offset += rr.Length;
+ break;
+ case 202: //sd
+ var sd = new RtcpSourceDescriptionPacket();
+ sd.Parse(packets, offset);
+ offset += sd.Length;
+ break;
+ case 203: // bye
+ var bye = new RtcpByePacket();
+ bye.Parse(packets, offset);
+ receivedGoodBye = true;
+ OnPacketReceived(new RtcpPacketReceivedArgs(bye));
+ offset += bye.Length;
+ break;
+ case 204: // app
+ var app = new RtcpAppPacket();
+ app.Parse(packets, offset);
+ OnPacketReceived(new RtcpPacketReceivedArgs(app));
+ offset += app.Length;
+ break;
+ }
+ }
+
+ }
+ }
+ finally
+ {
+ switch (_transmissionMode)
+ {
+ case TransmissionMode.Multicast:
+ _udpClient.DropMulticastGroup(_multicastEndPoint.Address);
+ _udpClient.Close();
+ break;
+ case TransmissionMode.Unicast:
+ _udpClient.Close();
+ break;
+ }
+ }
+ }
+ catch (ThreadAbortException)
+ {
+ }
+ catch (Exception ex)
+ {
+ _logger.Info(string.Format("SAT>IP : RTCP listener thread exception"), ex);
+ return;
+ }
+ _logger.Info("SAT>IP : RTCP listener thread stopping");
+ }
+ public delegate void PacketReceivedHandler(object sender, RtcpPacketReceivedArgs e);
+ public event PacketReceivedHandler PacketReceived;
+ public class RtcpPacketReceivedArgs : EventArgs
+ {
+ public Object Packet { get; private set; }
+
+ public RtcpPacketReceivedArgs(Object packet)
+ {
+ Packet = packet;
+ }
+ }
+ protected void OnPacketReceived(RtcpPacketReceivedArgs args)
+ {
+ if (PacketReceived != null)
+ {
+ PacketReceived(this, args);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs
new file mode 100644
index 000000000..0a949eb7e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpPacket.cs
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ public abstract class RtcpPacket
+ {
+ public int Version { get; private set; }
+ public bool Padding { get; private set; }
+ public int ReportCount { get; private set; }
+ public int Type { get; private set; }
+ public int Length { get; private set; }
+
+ public virtual void Parse(byte[] buffer, int offset)
+ {
+ Version = buffer[offset] >> 6;
+ Padding = (buffer[offset] & 0x20) != 0;
+ ReportCount = buffer[offset] & 0x1f;
+ Type = buffer[offset + 1];
+ Length = (Utils.Convert2BytesToInt(buffer, offset + 2) * 4) + 4;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs
new file mode 100644
index 000000000..abb863652
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpReceiverReportPacket.cs
@@ -0,0 +1,68 @@
+using System.Collections.ObjectModel;
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ public class RtcpReceiverReportPacket :RtcpPacket
+ {
+ public string SynchronizationSource { get; private set; }
+ public Collection<ReportBlock> ReportBlocks { get; private set; }
+ public byte[] ProfileExtension { get; private set; }
+ public override void Parse(byte[] buffer, int offset)
+ {
+ base.Parse(buffer, offset);
+ SynchronizationSource = Utils.ConvertBytesToString(buffer, offset + 4, 4);
+
+ ReportBlocks = new Collection<ReportBlock>();
+ int index = 8;
+
+ while (ReportBlocks.Count < ReportCount)
+ {
+ ReportBlock reportBlock = new ReportBlock();
+ reportBlock.Process(buffer, offset + index);
+ ReportBlocks.Add(reportBlock);
+ index += reportBlock.BlockLength;
+ }
+
+ if (index < Length)
+ {
+ ProfileExtension = new byte[Length - index];
+
+ for (int extensionIndex = 0; index < Length; index++)
+ {
+ ProfileExtension[extensionIndex] = buffer[offset + index];
+ extensionIndex++;
+ }
+ }
+ }
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("Receiver Report.\n");
+ sb.AppendFormat("Version : {0} .\n", Version);
+ sb.AppendFormat("Padding : {0} .\n", Padding);
+ sb.AppendFormat("Report Count : {0} .\n", ReportCount);
+ sb.AppendFormat("PacketType: {0} .\n", Type);
+ sb.AppendFormat("Length : {0} .\n", Length);
+ sb.AppendFormat("SynchronizationSource : {0} .\n", SynchronizationSource);
+ sb.AppendFormat(".\n");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs
new file mode 100644
index 000000000..dda5d6a03
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSenderReportPacket.cs
@@ -0,0 +1,105 @@
+using System.Collections.ObjectModel;
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ public class RtcpSenderReportPacket : RtcpPacket
+ {
+ #region Properties
+ /// <summary>
+ /// Get the synchronization source.
+ /// </summary>
+ public int SynchronizationSource { get; private set; }
+ /// <summary>
+ /// Get the NPT timestamp.
+ /// </summary>
+ public long NPTTimeStamp { get; private set; }
+ /// <summary>
+ /// Get the RTP timestamp.
+ /// </summary>
+ public int RTPTimeStamp { get; private set; }
+ /// <summary>
+ /// Get the packet count.
+ /// </summary>
+ public int SenderPacketCount { get; private set; }
+ /// <summary>
+ /// Get the octet count.
+ /// </summary>
+ public int SenderOctetCount { get; private set; }
+ /// <summary>
+ /// Get the list of report blocks.
+ /// </summary>
+ public Collection<ReportBlock> ReportBlocks { get; private set; }
+ /// <summary>
+ /// Get the profile extension data.
+ /// </summary>
+ public byte[] ProfileExtension { get; private set; }
+ #endregion
+
+ public override void Parse(byte[] buffer, int offset)
+ {
+ base.Parse(buffer, offset);
+ SynchronizationSource = Utils.Convert4BytesToInt(buffer, offset + 4);
+ NPTTimeStamp = Utils.Convert8BytesToLong(buffer, offset + 8);
+ RTPTimeStamp = Utils.Convert4BytesToInt(buffer, offset + 16);
+ SenderPacketCount = Utils.Convert4BytesToInt(buffer, offset + 20);
+ SenderOctetCount = Utils.Convert4BytesToInt(buffer, offset + 24);
+
+ ReportBlocks = new Collection<ReportBlock>();
+ int index = 28;
+
+ while (ReportBlocks.Count < ReportCount)
+ {
+ ReportBlock reportBlock = new ReportBlock();
+ reportBlock.Process(buffer, offset + index);
+ ReportBlocks.Add(reportBlock);
+ index += reportBlock.BlockLength;
+ }
+
+ if (index < Length)
+ {
+ ProfileExtension = new byte[Length - index];
+
+ for (int extensionIndex = 0; index < Length; index++)
+ {
+ ProfileExtension[extensionIndex] = buffer[offset + index];
+ extensionIndex++;
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("Sender Report.\n");
+ sb.AppendFormat("Version : {0} .\n", Version);
+ sb.AppendFormat("Padding : {0} .\n", Padding);
+ sb.AppendFormat("Report Count : {0} .\n", ReportCount);
+ sb.AppendFormat("PacketType: {0} .\n", Type);
+ sb.AppendFormat("Length : {0} .\n", Length);
+ sb.AppendFormat("SynchronizationSource : {0} .\n", SynchronizationSource);
+ sb.AppendFormat("NTP Timestamp : {0} .\n", Utils.NptTimestampToDateTime(NPTTimeStamp));
+ sb.AppendFormat("RTP Timestamp : {0} .\n", RTPTimeStamp);
+ sb.AppendFormat("Sender PacketCount : {0} .\n", SenderPacketCount);
+ sb.AppendFormat("Sender Octet Count : {0} .\n", SenderOctetCount);
+ sb.AppendFormat(".\n");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs
new file mode 100644
index 000000000..0a95a4413
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/RtcpSourceDescriptionPacket.cs
@@ -0,0 +1,57 @@
+using System.Collections.ObjectModel;
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ class RtcpSourceDescriptionPacket :RtcpPacket
+ { /// <summary>
+ /// Get the list of source descriptions.
+ /// </summary>
+ public Collection<SourceDescriptionBlock> Descriptions;
+ public override void Parse(byte[] buffer, int offset)
+ {
+ base.Parse(buffer, offset);
+ Descriptions = new Collection<SourceDescriptionBlock>();
+
+ int index = 4;
+
+ while (Descriptions.Count < ReportCount)
+ {
+ SourceDescriptionBlock descriptionBlock = new SourceDescriptionBlock();
+ descriptionBlock.Process(buffer, offset + index);
+ Descriptions.Add(descriptionBlock);
+ index += descriptionBlock.BlockLength;
+ }
+ }
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("Source Description.\n");
+ sb.AppendFormat("Version : {0} .\n", Version);
+ sb.AppendFormat("Padding : {0} .\n", Padding);
+ sb.AppendFormat("Report Count : {0} .\n", ReportCount);
+ sb.AppendFormat("PacketType: {0} .\n", Type);
+ sb.AppendFormat("Length : {0} .\n", Length);
+ sb.AppendFormat("Descriptions : {0} .\n", Descriptions);
+
+ sb.AppendFormat(".\n");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs
new file mode 100644
index 000000000..bf56087cd
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionBlock.cs
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System.Collections.ObjectModel;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ class SourceDescriptionBlock
+ {
+ /// <summary>
+ /// Get the length of the block.
+ /// </summary>
+ public int BlockLength { get { return (blockLength + (blockLength % 4)); } }
+
+ /// <summary>
+ /// Get the synchronization source.
+ /// </summary>
+ public string SynchronizationSource { get; private set; }
+ /// <summary>
+ /// Get the list of source descriptioni items.
+ /// </summary>
+ public Collection<SourceDescriptionItem> Items;
+
+ private int blockLength;
+
+ public void Process(byte[] buffer, int offset)
+ {
+ SynchronizationSource = Utils.ConvertBytesToString(buffer, offset, 4);
+ Items = new Collection<SourceDescriptionItem>();
+ int index = 4;
+ bool done = false;
+ do
+ {
+ SourceDescriptionItem item = new SourceDescriptionItem();
+ item.Process(buffer, offset + index);
+
+ if (item.Type != 0)
+ {
+ Items.Add(item);
+ index += item.ItemLength;
+ blockLength += item.ItemLength;
+ }
+ else
+ {
+ blockLength++;
+ done = true;
+ }
+ }
+ while (!done);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs
new file mode 100644
index 000000000..5dd033642
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtcp/SourceDescriptionItem.cs
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtcp
+{
+ /// <summary>
+ /// The class that describes a source description item.
+ /// </summary>
+ public class SourceDescriptionItem
+ {
+ /// <summary>
+ /// Get the type.
+ /// </summary>
+ public int Type { get; private set; }
+ /// <summary>
+ /// Get the text.
+ /// </summary>
+ public string Text { get; private set; }
+
+ /// <summary>
+ /// Get the length of the item.
+ /// </summary>
+ public int ItemLength { get { return (Text.Length + 2); } }
+
+ /// <summary>
+ /// Initialize a new instance of the SourceDescriptionItem class.
+ /// </summary>
+ public SourceDescriptionItem() { }
+
+ /// <summary>
+ /// Unpack the data in a packet.
+ /// </summary>
+ /// <param name="buffer">The buffer containing the packet.</param>
+ /// <param name="offset">The offset to the first byte of the packet within the buffer.</param>
+ /// <returns>An ErrorSpec instance if an error occurs; null otherwise.</returns>
+ public void Process(byte[] buffer, int offset)
+ {
+ Type = buffer[offset];
+ if (Type != 0)
+ {
+ int length = buffer[offset + 1];
+ Text = Utils.ConvertBytesToString(buffer, offset + 2, length);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs
new file mode 100644
index 000000000..ea6a9ba6a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpListener.cs
@@ -0,0 +1,160 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using MediaBrowser.Model.Logging;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtp
+{
+ public class RtpListener
+ {
+ private readonly ILogger _logger;
+ private AutoResetEvent _rtpListenerThreadStopEvent;
+ private Thread _rtpListenerThread;
+ private UdpClient _udpClient;
+ private IPEndPoint _multicastEndPoint;
+ private IPEndPoint _serverEndPoint;
+ private TransmissionMode _transmissionMode;
+ public RtpListener(String address, int port,TransmissionMode mode,ILogger logger)
+ {
+ _logger = logger;
+ _transmissionMode = mode;
+ switch (mode)
+ {
+ case TransmissionMode.Unicast:
+ _udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(address), port));
+ _serverEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ break;
+ case TransmissionMode.Multicast:
+ _multicastEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
+ _serverEndPoint = null;
+ _udpClient = new UdpClient();
+ _udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
+ _udpClient.ExclusiveAddressUse = false;
+ _udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, _multicastEndPoint.Port));
+ _udpClient.JoinMulticastGroup(_multicastEndPoint.Address);
+ break;
+ }
+ //StartRtpListenerThread();
+ }
+ public void StartRtpListenerThread()
+ {
+ // Kill the existing thread if it is in "zombie" state.
+ if (_rtpListenerThread != null && !_rtpListenerThread.IsAlive)
+ {
+ StopRtpListenerThread();
+ }
+
+ if (_rtpListenerThread == null)
+ {
+ _logger.Info("SAT>IP : starting new RTP listener thread");
+ _rtpListenerThreadStopEvent = new AutoResetEvent(false);
+ _rtpListenerThread = new Thread(new ThreadStart(RtpListenerThread));
+ _rtpListenerThread.Name = string.Format("SAT>IP tuner RTP listener");
+ _rtpListenerThread.IsBackground = true;
+ _rtpListenerThread.Priority = ThreadPriority.Lowest;
+ _rtpListenerThread.Start();
+ }
+ }
+
+ public void StopRtpListenerThread()
+ {
+ if (_rtpListenerThread != null)
+ {
+ if (!_rtpListenerThread.IsAlive)
+ {
+ _logger.Info("SAT>IP : aborting old RTP listener thread");
+ _rtpListenerThread.Abort();
+ }
+ else
+ {
+ _rtpListenerThreadStopEvent.Set();
+ if (!_rtpListenerThread.Join(400 * 2))
+ {
+ _logger.Info("SAT>IP : failed to join RTP listener thread, aborting thread");
+ _rtpListenerThread.Abort();
+ }
+ }
+ _rtpListenerThread = null;
+ if (_rtpListenerThreadStopEvent != null)
+ {
+ _rtpListenerThreadStopEvent.Close();
+ _rtpListenerThreadStopEvent = null;
+ }
+ }
+ }
+
+ private void RtpListenerThread()
+ {
+ try
+ {
+ try
+ {
+
+ while (!_rtpListenerThreadStopEvent.WaitOne(1))
+ {
+ byte[] receivedbytes = _udpClient.Receive(ref _serverEndPoint);
+ RtpPacket packet = RtpPacket.Decode(receivedbytes);
+ OnPacketReceived(new RtpPacketReceivedArgs(packet));
+ }
+ }
+ finally
+ {
+ switch (_transmissionMode)
+ {
+ case TransmissionMode.Multicast:
+ _udpClient.DropMulticastGroup(_multicastEndPoint.Address);
+ _udpClient.Close();
+ break;
+ case TransmissionMode.Unicast:
+ _udpClient.Close();
+ break;
+ }
+ }
+ }
+ catch (ThreadAbortException)
+ {
+ }
+ catch (Exception ex)
+ {
+ _logger.Info(string.Format("SAT>IP : RTP listener thread exception"), ex);
+ return;
+ }
+ _logger.Info("SAT>IP : RTP listener thread stopping");
+ }
+ public delegate void PacketReceivedHandler(object sender, RtpPacketReceivedArgs e);
+ public event PacketReceivedHandler PacketReceived;
+ public class RtpPacketReceivedArgs : EventArgs
+ {
+ public RtpPacket Packet { get; private set; }
+
+ public RtpPacketReceivedArgs(RtpPacket packet)
+ {
+ Packet = packet;
+ }
+ }
+ protected void OnPacketReceived(RtpPacketReceivedArgs args)
+ {
+ if (PacketReceived != null)
+ {
+ PacketReceived(this, args);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs
new file mode 100644
index 000000000..489d7f087
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtp/RtpPacket.cs
@@ -0,0 +1,116 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using System;
+using System.Collections.ObjectModel;
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtp
+{
+ public class RtpPacket
+ {
+ private static int MinHeaderLength = 12;
+ public int HeaderSize = MinHeaderLength;
+ public int Version { get; set; }
+ public Boolean Padding { get; set; }
+ public Boolean Extension { get; set; }
+ public int ContributingSourceCount { get; set; }
+ public Boolean Marker { get; set; }
+ public int PayloadType { get; set; }
+ public int SequenceNumber { get; set; }
+ public long TimeStamp { get; set; }
+ public long SynchronizationSource { get; set; }
+ public Collection<string> ContributingSources { get; private set; }
+ public int ExtensionHeaderId = 0;
+ public int ExtensionHeaderLength = 0;
+ public bool HasPayload { get; set; }
+ public byte[] Payload { get; set; }
+ public RtpPacket()
+ {
+
+ }
+ public static RtpPacket Decode(byte[] buffer)
+ {
+ var packet = new RtpPacket();
+ packet.Version = buffer[0] >> 6;
+ packet.Padding = (buffer[0] & 0x20) != 0;
+ packet.Extension = (buffer[0] & 0x10) != 0;
+ packet.ContributingSourceCount = buffer[0] & 0x0f;
+
+ packet.Marker = (buffer[1] & 0x80) != 0;
+ packet.PayloadType = buffer[1] & 0x7f;
+
+ packet.SequenceNumber = Utils.Convert2BytesToInt(buffer, 2);
+ packet.TimeStamp = Utils.Convert4BytesToLong(buffer, 4);
+ packet.SynchronizationSource = Utils.Convert4BytesToLong(buffer, 8);
+
+ int index = 12;
+
+ if (packet.ContributingSourceCount != 0)
+ {
+ packet.ContributingSources = new Collection<string>();
+
+ while (packet.ContributingSources.Count < packet.ContributingSourceCount)
+ {
+ packet.ContributingSources.Add(Utils.ConvertBytesToString(buffer, index, 4));
+ index += 4;
+ }
+ }
+ var dataoffset = 0;
+ if (!packet.Extension)
+ dataoffset = index;
+ else
+ {
+ packet.ExtensionHeaderId = Utils.Convert2BytesToInt(buffer, index);
+ packet.ExtensionHeaderLength = Utils.Convert2BytesToInt(buffer, index + 2);
+ dataoffset = index + packet.ExtensionHeaderLength + 4;
+ }
+
+ var dataLength = buffer.Length - dataoffset;
+ if (dataLength > dataoffset)
+ {
+ packet.HasPayload = true;
+ packet.Payload = new byte[dataLength];
+ Array.Copy(buffer, dataoffset, packet.Payload, 0, dataLength);
+ }
+ else
+ {
+ packet.HasPayload = false;
+ }
+ return packet;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("RTP Packet");
+ sb.AppendFormat("Version: {0} \n", Version);
+ sb.AppendFormat("Padding: {0} \n", Padding);
+ sb.AppendFormat("Extension: {0} \n", Extension);
+ sb.AppendFormat("Contributing Source Identifiers Count: {0} \n", ContributingSourceCount);
+ sb.AppendFormat("Marker: {0} \n", Marker);
+ sb.AppendFormat("Payload Type: {0} \n", PayloadType);
+ sb.AppendFormat("Sequence Number: {0} \n", SequenceNumber);
+ sb.AppendFormat("Timestamp: {0} .\n", TimeStamp);
+ sb.AppendFormat("Synchronization Source Identifier: {0} \n", SynchronizationSource);
+ sb.AppendFormat("\n");
+ return sb.ToString();
+ }
+
+ }
+
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs
new file mode 100644
index 000000000..5f286f1db
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs
@@ -0,0 +1,88 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using System.Collections.Generic;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp
+{
+ /// <summary>
+ /// Standard RTSP request methods.
+ /// </summary>
+ public sealed class RtspMethod
+ {
+ public override int GetHashCode()
+ {
+ return (_name != null ? _name.GetHashCode() : 0);
+ }
+
+ private readonly string _name;
+ private static readonly IDictionary<string, RtspMethod> _values = new Dictionary<string, RtspMethod>();
+
+ public static readonly RtspMethod Describe = new RtspMethod("DESCRIBE");
+ public static readonly RtspMethod Announce = new RtspMethod("ANNOUNCE");
+ public static readonly RtspMethod GetParameter = new RtspMethod("GET_PARAMETER");
+ public static readonly RtspMethod Options = new RtspMethod("OPTIONS");
+ public static readonly RtspMethod Pause = new RtspMethod("PAUSE");
+ public static readonly RtspMethod Play = new RtspMethod("PLAY");
+ public static readonly RtspMethod Record = new RtspMethod("RECORD");
+ public static readonly RtspMethod Redirect = new RtspMethod("REDIRECT");
+ public static readonly RtspMethod Setup = new RtspMethod("SETUP");
+ public static readonly RtspMethod SetParameter = new RtspMethod("SET_PARAMETER");
+ public static readonly RtspMethod Teardown = new RtspMethod("TEARDOWN");
+
+ private RtspMethod(string name)
+ {
+ _name = name;
+ _values.Add(name, this);
+ }
+
+ public override string ToString()
+ {
+ return _name;
+ }
+
+ public override bool Equals(object obj)
+ {
+ var method = obj as RtspMethod;
+ if (method != null && this == method)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ public static ICollection<RtspMethod> Values
+ {
+ get { return _values.Values; }
+ }
+
+ public static explicit operator RtspMethod(string name)
+ {
+ RtspMethod value;
+ if (!_values.TryGetValue(name, out value))
+ {
+ return null;
+ }
+ return value;
+ }
+
+ public static implicit operator string(RtspMethod method)
+ {
+ return method._name;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs
new file mode 100644
index 000000000..600eda02d
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs
@@ -0,0 +1,140 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using System.Collections.Generic;
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp
+{
+ /// <summary>
+ /// A simple class that can be used to serialise RTSP requests.
+ /// </summary>
+ public class RtspRequest
+ {
+ private readonly RtspMethod _method;
+ private readonly string _uri;
+ private readonly int _majorVersion;
+ private readonly int _minorVersion;
+ private IDictionary<string, string> _headers = new Dictionary<string, string>();
+ private string _body = string.Empty;
+
+ /// <summary>
+ /// Initialise a new instance of the <see cref="RtspRequest"/> class.
+ /// </summary>
+ /// <param name="method">The request method.</param>
+ /// <param name="uri">The request URI</param>
+ /// <param name="majorVersion">The major version number.</param>
+ /// <param name="minorVersion">The minor version number.</param>
+ public RtspRequest(RtspMethod method, string uri, int majorVersion, int minorVersion)
+ {
+ _method = method;
+ _uri = uri;
+ _majorVersion = majorVersion;
+ _minorVersion = minorVersion;
+ }
+
+ /// <summary>
+ /// Get the request method.
+ /// </summary>
+ public RtspMethod Method
+ {
+ get
+ {
+ return _method;
+ }
+ }
+
+ /// <summary>
+ /// Get the request URI.
+ /// </summary>
+ public string Uri
+ {
+ get
+ {
+ return _uri;
+ }
+ }
+
+ /// <summary>
+ /// Get the request major version number.
+ /// </summary>
+ public int MajorVersion
+ {
+ get
+ {
+ return _majorVersion;
+ }
+ }
+
+ /// <summary>
+ /// Get the request minor version number.
+ /// </summary>
+ public int MinorVersion
+ {
+ get
+ {
+ return _minorVersion;
+ }
+ }
+
+ /// <summary>
+ /// Get or set the request headers.
+ /// </summary>
+ public IDictionary<string, string> Headers
+ {
+ get
+ {
+ return _headers;
+ }
+ set
+ {
+ _headers = value;
+ }
+ }
+
+ /// <summary>
+ /// Get or set the request body.
+ /// </summary>
+ public string Body
+ {
+ get
+ {
+ return _body;
+ }
+ set
+ {
+ _body = value;
+ }
+ }
+
+ /// <summary>
+ /// Serialise this request.
+ /// </summary>
+ /// <returns>raw request bytes</returns>
+ public byte[] Serialise()
+ {
+ var request = new StringBuilder();
+ request.AppendFormat("{0} {1} RTSP/{2}.{3}\r\n", _method, _uri, _majorVersion, _minorVersion);
+ foreach (var header in _headers)
+ {
+ request.AppendFormat("{0}: {1}\r\n", header.Key, header.Value);
+ }
+ request.AppendFormat("\r\n{0}", _body);
+ return Encoding.UTF8.GetBytes(request.ToString());
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs
new file mode 100644
index 000000000..97290623b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs
@@ -0,0 +1,149 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp
+{
+ /// <summary>
+ /// A simple class that can be used to deserialise RTSP responses.
+ /// </summary>
+ public class RtspResponse
+ {
+ private static readonly Regex RegexStatusLine = new Regex(@"RTSP/(\d+)\.(\d+)\s+(\d+)\s+([^.]+?)\r\n(.*)", RegexOptions.Singleline);
+
+ private int _majorVersion = 1;
+ private int _minorVersion;
+ private RtspStatusCode _statusCode;
+ private string _reasonPhrase;
+ private IDictionary<string, string> _headers;
+ private string _body;
+
+ /// <summary>
+ /// Initialise a new instance of the <see cref="RtspResponse"/> class.
+ /// </summary>
+ private RtspResponse()
+ {
+ }
+
+ /// <summary>
+ /// Get the response major version number.
+ /// </summary>
+ public int MajorVersion
+ {
+ get
+ {
+ return _majorVersion;
+ }
+ }
+
+ /// <summary>
+ /// Get the response minor version number.
+ /// </summary>
+ public int MinorVersion
+ {
+ get
+ {
+ return _minorVersion;
+ }
+ }
+
+ /// <summary>
+ /// Get the response status code.
+ /// </summary>
+ public RtspStatusCode StatusCode
+ {
+ get
+ {
+ return _statusCode;
+ }
+ }
+
+ /// <summary>
+ /// Get the response reason phrase.
+ /// </summary>
+ public string ReasonPhrase
+ {
+ get
+ {
+ return _reasonPhrase;
+ }
+ }
+
+ /// <summary>
+ /// Get the response headers.
+ /// </summary>
+ public IDictionary<string, string> Headers
+ {
+ get
+ {
+ return _headers;
+ }
+ }
+
+ /// <summary>
+ /// Get the response body.
+ /// </summary>
+ public string Body
+ {
+ get
+ {
+ return _body;
+ }
+ set
+ {
+ _body = value;
+ }
+ }
+
+ /// <summary>
+ /// Deserialise/parse an RTSP response.
+ /// </summary>
+ /// <param name="responseBytes">The raw response bytes.</param>
+ /// <param name="responseByteCount">The number of valid bytes in the response.</param>
+ /// <returns>a response object</returns>
+ public static RtspResponse Deserialise(byte[] responseBytes, int responseByteCount)
+ {
+ var response = new RtspResponse();
+ var responseString = Encoding.UTF8.GetString(responseBytes, 0, responseByteCount);
+
+ var m = RegexStatusLine.Match(responseString);
+ if (m.Success)
+ {
+ response._majorVersion = int.Parse(m.Groups[1].Captures[0].Value);
+ response._minorVersion = int.Parse(m.Groups[2].Captures[0].Value);
+ response._statusCode = (RtspStatusCode)int.Parse(m.Groups[3].Captures[0].Value);
+ response._reasonPhrase = m.Groups[4].Captures[0].Value;
+ responseString = m.Groups[5].Captures[0].Value;
+ }
+
+ var sections = responseString.Split(new[] { "\r\n\r\n" }, StringSplitOptions.None);
+ response._body = sections[1];
+ var headers = sections[0].Split(new[] { "\r\n" }, StringSplitOptions.None);
+ response._headers = new Dictionary<string, string>();
+ foreach (var headerInfo in headers.Select(header => header.Split(':')))
+ {
+ response._headers.Add(headerInfo[0], headerInfo[1].Trim());
+ }
+ return response;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs
new file mode 100644
index 000000000..0f8682b7c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs
@@ -0,0 +1,688 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Net.Sockets;
+using System.Text.RegularExpressions;
+using MediaBrowser.Model.Logging;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp
+{
+ public class RtspSession : IDisposable
+ {
+ #region Private Fields
+ private static readonly Regex RegexRtspSessionHeader = new Regex(@"\s*([^\s;]+)(;timeout=(\d+))?");
+ private const int DefaultRtspSessionTimeout = 30; // unit = s
+ private static readonly Regex RegexDescribeResponseSignalInfo = new Regex(@";tuner=\d+,(\d+),(\d+),(\d+),", RegexOptions.Singleline | RegexOptions.IgnoreCase);
+ private string _address;
+ private string _rtspSessionId;
+
+ public string RtspSessionId
+ {
+ get { return _rtspSessionId; }
+ set { _rtspSessionId = value; }
+ }
+ private int _rtspSessionTimeToLive = 0;
+ private string _rtspStreamId;
+ private int _clientRtpPort;
+ private int _clientRtcpPort;
+ private int _serverRtpPort;
+ private int _serverRtcpPort;
+ private int _rtpPort;
+ private int _rtcpPort;
+ private string _rtspStreamUrl;
+ private string _destination;
+ private string _source;
+ private string _transport;
+ private int _signalLevel;
+ private int _signalQuality;
+ private Socket _rtspSocket;
+ private int _rtspSequenceNum = 1;
+ private bool _disposed = false;
+ private readonly ILogger _logger;
+ #endregion
+
+ #region Constructor
+
+ public RtspSession(string address, ILogger logger)
+ {
+ if (string.IsNullOrWhiteSpace(address))
+ {
+ throw new ArgumentNullException("address");
+ }
+
+ _address = address;
+ _logger = logger;
+
+ _logger.Info("Creating RtspSession with url {0}", address);
+ }
+ ~RtspSession()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ #region Properties
+
+ #region Rtsp
+
+ public string RtspStreamId
+ {
+ get { return _rtspStreamId; }
+ set { if (_rtspStreamId != value) { _rtspStreamId = value; OnPropertyChanged("RtspStreamId"); } }
+ }
+ public string RtspStreamUrl
+ {
+ get { return _rtspStreamUrl; }
+ set { if (_rtspStreamUrl != value) { _rtspStreamUrl = value; OnPropertyChanged("RtspStreamUrl"); } }
+ }
+
+ public int RtspSessionTimeToLive
+ {
+ get
+ {
+ if (_rtspSessionTimeToLive == 0)
+ _rtspSessionTimeToLive = DefaultRtspSessionTimeout;
+ return _rtspSessionTimeToLive * 1000 - 20;
+ }
+ set { if (_rtspSessionTimeToLive != value) { _rtspSessionTimeToLive = value; OnPropertyChanged("RtspSessionTimeToLive"); } }
+ }
+
+ #endregion
+
+ #region Rtp Rtcp
+
+ /// <summary>
+ /// The LocalEndPoint Address
+ /// </summary>
+ public string Destination
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_destination))
+ {
+ var result = "";
+ var host = Dns.GetHostName();
+ var hostentry = Dns.GetHostEntry(host);
+ foreach (var ip in hostentry.AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork))
+ {
+ result = ip.ToString();
+ }
+
+ _destination = result;
+ }
+ return _destination;
+ }
+ set
+ {
+ if (_destination != value)
+ {
+ _destination = value;
+ OnPropertyChanged("Destination");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The RemoteEndPoint Address
+ /// </summary>
+ public string Source
+ {
+ get { return _source; }
+ set
+ {
+ if (_source != value)
+ {
+ _source = value;
+ OnPropertyChanged("Source");
+ }
+ }
+ }
+
+ /// <summary>
+ /// The Media Data Delivery RemoteEndPoint Port if we use Unicast
+ /// </summary>
+ public int ServerRtpPort
+ {
+ get
+ {
+ return _serverRtpPort;
+ }
+ set { if (_serverRtpPort != value) { _serverRtpPort = value; OnPropertyChanged("ServerRtpPort"); } }
+ }
+
+ /// <summary>
+ /// The Media Metadata Delivery RemoteEndPoint Port if we use Unicast
+ /// </summary>
+ public int ServerRtcpPort
+ {
+ get { return _serverRtcpPort; }
+ set { if (_serverRtcpPort != value) { _serverRtcpPort = value; OnPropertyChanged("ServerRtcpPort"); } }
+ }
+
+ /// <summary>
+ /// The Media Data Delivery LocalEndPoint Port if we use Unicast
+ /// </summary>
+ public int ClientRtpPort
+ {
+ get { return _clientRtpPort; }
+ set { if (_clientRtpPort != value) { _clientRtpPort = value; OnPropertyChanged("ClientRtpPort"); } }
+ }
+
+ /// <summary>
+ /// The Media Metadata Delivery LocalEndPoint Port if we use Unicast
+ /// </summary>
+ public int ClientRtcpPort
+ {
+ get { return _clientRtcpPort; }
+ set { if (_clientRtcpPort != value) { _clientRtcpPort = value; OnPropertyChanged("ClientRtcpPort"); } }
+ }
+
+ /// <summary>
+ /// The Media Data Delivery RemoteEndPoint Port if we use Multicast
+ /// </summary>
+ public int RtpPort
+ {
+ get { return _rtpPort; }
+ set { if (_rtpPort != value) { _rtpPort = value; OnPropertyChanged("RtpPort"); } }
+ }
+
+ /// <summary>
+ /// The Media Meta Delivery RemoteEndPoint Port if we use Multicast
+ /// </summary>
+ public int RtcpPort
+ {
+ get { return _rtcpPort; }
+ set { if (_rtcpPort != value) { _rtcpPort = value; OnPropertyChanged("RtcpPort"); } }
+ }
+
+ #endregion
+
+ public string Transport
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(_transport))
+ {
+ _transport = "unicast";
+ }
+ return _transport;
+ }
+ set
+ {
+ if (_transport != value)
+ {
+ _transport = value;
+ OnPropertyChanged("Transport");
+ }
+ }
+ }
+ public int SignalLevel
+ {
+ get { return _signalLevel; }
+ set { if (_signalLevel != value) { _signalLevel = value; OnPropertyChanged("SignalLevel"); } }
+ }
+ public int SignalQuality
+ {
+ get { return _signalQuality; }
+ set { if (_signalQuality != value) { _signalQuality = value; OnPropertyChanged("SignalQuality"); } }
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private void ProcessSessionHeader(string sessionHeader, string response)
+ {
+ if (!string.IsNullOrEmpty(sessionHeader))
+ {
+ var m = RegexRtspSessionHeader.Match(sessionHeader);
+ if (!m.Success)
+ {
+ _logger.Error("Failed to tune, RTSP {0} response session header {1} format not recognised", response, sessionHeader);
+ }
+ _rtspSessionId = m.Groups[1].Captures[0].Value;
+ _rtspSessionTimeToLive = m.Groups[3].Captures.Count == 1 ? int.Parse(m.Groups[3].Captures[0].Value) : DefaultRtspSessionTimeout;
+ }
+ }
+ private void ProcessTransportHeader(string transportHeader)
+ {
+ if (!string.IsNullOrEmpty(transportHeader))
+ {
+ var transports = transportHeader.Split(',');
+ foreach (var transport in transports)
+ {
+ if (transport.Trim().StartsWith("RTP/AVP"))
+ {
+ var sections = transport.Split(';');
+ foreach (var section in sections)
+ {
+ var parts = section.Split('=');
+ if (parts[0].Equals("server_port"))
+ {
+ var ports = parts[1].Split('-');
+ _serverRtpPort = int.Parse(ports[0]);
+ _serverRtcpPort = int.Parse(ports[1]);
+ }
+ else if (parts[0].Equals("destination"))
+ {
+ _destination = parts[1];
+ }
+ else if (parts[0].Equals("port"))
+ {
+ var ports = parts[1].Split('-');
+ _rtpPort = int.Parse(ports[0]);
+ _rtcpPort = int.Parse(ports[1]);
+ }
+ else if (parts[0].Equals("ttl"))
+ {
+ _rtspSessionTimeToLive = int.Parse(parts[1]);
+ }
+ else if (parts[0].Equals("source"))
+ {
+ _source = parts[1];
+ }
+ else if (parts[0].Equals("client_port"))
+ {
+ var ports = parts[1].Split('-');
+ var rtp = int.Parse(ports[0]);
+ var rtcp = int.Parse(ports[1]);
+ //if (!rtp.Equals(_rtpPort))
+ //{
+ // Logger.Error("SAT>IP base: server specified RTP client port {0} instead of {1}", rtp, _rtpPort);
+ //}
+ //if (!rtcp.Equals(_rtcpPort))
+ //{
+ // Logger.Error("SAT>IP base: server specified RTCP client port {0} instead of {1}", rtcp, _rtcpPort);
+ //}
+ _rtpPort = rtp;
+ _rtcpPort = rtcp;
+ }
+ }
+ }
+ }
+ }
+ }
+ private void Connect()
+ {
+ _rtspSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ var ip = IPAddress.Parse(_address);
+ var rtspEndpoint = new IPEndPoint(ip, 554);
+ _rtspSocket.Connect(rtspEndpoint);
+ }
+ private void Disconnect()
+ {
+ if (_rtspSocket != null && _rtspSocket.Connected)
+ {
+ _rtspSocket.Shutdown(SocketShutdown.Both);
+ _rtspSocket.Close();
+ }
+ }
+ private void SendRequest(RtspRequest request)
+ {
+ if (_rtspSocket == null)
+ {
+ Connect();
+ }
+ try
+ {
+ request.Headers.Add("CSeq", _rtspSequenceNum.ToString());
+ _rtspSequenceNum++;
+ byte[] requestBytes = request.Serialise();
+ if (_rtspSocket != null)
+ {
+ var requestBytesCount = _rtspSocket.Send(requestBytes, requestBytes.Length, SocketFlags.None);
+ if (requestBytesCount < 1)
+ {
+
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.Error(e.Message);
+ }
+ }
+ private void ReceiveResponse(out RtspResponse response)
+ {
+ response = null;
+ var responseBytesCount = 0;
+ byte[] responseBytes = new byte[1024];
+ try
+ {
+ responseBytesCount = _rtspSocket.Receive(responseBytes, responseBytes.Length, SocketFlags.None);
+ response = RtspResponse.Deserialise(responseBytes, responseBytesCount);
+ string contentLengthString;
+ int contentLength = 0;
+ if (response.Headers.TryGetValue("Content-Length", out contentLengthString))
+ {
+ contentLength = int.Parse(contentLengthString);
+ if ((string.IsNullOrEmpty(response.Body) && contentLength > 0) || response.Body.Length < contentLength)
+ {
+ if (response.Body == null)
+ {
+ response.Body = string.Empty;
+ }
+ while (responseBytesCount > 0 && response.Body.Length < contentLength)
+ {
+ responseBytesCount = _rtspSocket.Receive(responseBytes, responseBytes.Length, SocketFlags.None);
+ response.Body += System.Text.Encoding.UTF8.GetString(responseBytes, 0, responseBytesCount);
+ }
+ }
+ }
+ }
+ catch (SocketException)
+ {
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ public RtspStatusCode Setup(string query, string transporttype)
+ {
+
+ RtspRequest request;
+ RtspResponse response;
+ //_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
+ if ((_rtspSocket == null))
+ {
+ Connect();
+ }
+ if (string.IsNullOrEmpty(_rtspSessionId))
+ {
+ request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0);
+ switch (transporttype)
+ {
+ case "multicast":
+ request.Headers.Add("Transport", string.Format("RTP/AVP;multicast"));
+ break;
+ case "unicast":
+ var activeTcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections();
+ var usedPorts = new HashSet<int>();
+ foreach (var connection in activeTcpConnections)
+ {
+ usedPorts.Add(connection.LocalEndPoint.Port);
+ }
+ for (var port = 40000; port <= 65534; port += 2)
+ {
+ if (!usedPorts.Contains(port) && !usedPorts.Contains(port + 1))
+ {
+
+ _clientRtpPort = port;
+ _clientRtcpPort = port + 1;
+ break;
+ }
+ }
+ request.Headers.Add("Transport", string.Format("RTP/AVP;unicast;client_port={0}-{1}", _clientRtpPort, _clientRtcpPort));
+ break;
+ }
+ }
+ else
+ {
+ request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0);
+ switch (transporttype)
+ {
+ case "multicast":
+ request.Headers.Add("Transport", string.Format("RTP/AVP;multicast"));
+ break;
+ case "unicast":
+ request.Headers.Add("Transport", string.Format("RTP/AVP;unicast;client_port={0}-{1}", _clientRtpPort, _clientRtcpPort));
+ break;
+ }
+
+ }
+ SendRequest(request);
+ ReceiveResponse(out response);
+
+ //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
+ //{
+ // Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase);
+ //}
+ if (!response.Headers.TryGetValue("com.ses.streamID", out _rtspStreamId))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate Stream ID header in RTSP SETUP response"));
+ }
+ string sessionHeader;
+ if (!response.Headers.TryGetValue("Session", out sessionHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP SETUP response"));
+ }
+ ProcessSessionHeader(sessionHeader, "Setup");
+ string transportHeader;
+ if (!response.Headers.TryGetValue("Transport", out transportHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate Transport header in RTSP SETUP response"));
+ }
+ ProcessTransportHeader(transportHeader);
+ return response.StatusCode;
+ }
+
+ public RtspStatusCode Play(string query)
+ {
+ if ((_rtspSocket == null))
+ {
+ Connect();
+ }
+ //_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
+ RtspResponse response;
+ string data;
+ if (string.IsNullOrEmpty(query))
+ {
+ data = string.Format("rtsp://{0}:{1}/stream={2}", _address,
+ 554, _rtspStreamId);
+ }
+ else
+ {
+ data = string.Format("rtsp://{0}:{1}/stream={2}?{3}", _address,
+ 554, _rtspStreamId, query);
+ }
+ var request = new RtspRequest(RtspMethod.Play, data, 1, 0);
+ request.Headers.Add("Session", _rtspSessionId);
+ SendRequest(request);
+ ReceiveResponse(out response);
+ //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
+ //{
+ // Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase);
+ //}
+ //Logger.Info("RtspSession-Play : \r\n {0}", response);
+ string sessionHeader;
+ if (!response.Headers.TryGetValue("Session", out sessionHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP Play response"));
+ }
+ ProcessSessionHeader(sessionHeader, "Play");
+ string rtpinfoHeader;
+ if (!response.Headers.TryGetValue("RTP-Info", out rtpinfoHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate Rtp-Info header in RTSP Play response"));
+ }
+ return response.StatusCode;
+ }
+
+ public RtspStatusCode Options()
+ {
+ if ((_rtspSocket == null))
+ {
+ Connect();
+ }
+ //_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
+ RtspRequest request;
+ RtspResponse response;
+
+
+ if (string.IsNullOrEmpty(_rtspSessionId))
+ {
+ request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
+ }
+ else
+ {
+ request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
+ request.Headers.Add("Session", _rtspSessionId);
+ }
+ SendRequest(request);
+ ReceiveResponse(out response);
+ //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
+ //{
+ // Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase);
+ //}
+ //Logger.Info("RtspSession-Options : \r\n {0}", response);
+ string sessionHeader;
+ if (!response.Headers.TryGetValue("Session", out sessionHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Options response"));
+ }
+ ProcessSessionHeader(sessionHeader, "Options");
+ string optionsHeader;
+ if (!response.Headers.TryGetValue("Public", out optionsHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to Options header in RTSP Options response"));
+ }
+ return response.StatusCode;
+ }
+
+ public RtspStatusCode Describe(out int level, out int quality)
+ {
+ if ((_rtspSocket == null))
+ {
+ Connect();
+ }
+ //_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
+ RtspRequest request;
+ RtspResponse response;
+ level = 0;
+ quality = 0;
+
+ if (string.IsNullOrEmpty(_rtspSessionId))
+ {
+ request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
+ request.Headers.Add("Accept", "application/sdp");
+
+ }
+ else
+ {
+ request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0);
+ request.Headers.Add("Accept", "application/sdp");
+ request.Headers.Add("Session", _rtspSessionId);
+ }
+ SendRequest(request);
+ ReceiveResponse(out response);
+ //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
+ //{
+ // Logger.Error("Failed to tune, non-OK RTSP Describe status code {0} {1}", response.StatusCode, response.ReasonPhrase);
+ //}
+ //Logger.Info("RtspSession-Describe : \r\n {0}", response);
+ string sessionHeader;
+ if (!response.Headers.TryGetValue("Session", out sessionHeader))
+ {
+ _logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Describe response"));
+ }
+ ProcessSessionHeader(sessionHeader, "Describe");
+ var m = RegexDescribeResponseSignalInfo.Match(response.Body);
+ if (m.Success)
+ {
+
+ //isSignalLocked = m.Groups[2].Captures[0].Value.Equals("1");
+ level = int.Parse(m.Groups[1].Captures[0].Value) * 100 / 255; // level: 0..255 => 0..100
+ quality = int.Parse(m.Groups[3].Captures[0].Value) * 100 / 15; // quality: 0..15 => 0..100
+
+ }
+ /*
+ v=0
+ o=- 1378633020884883 1 IN IP4 192.168.2.108
+ s=SatIPServer:1 4
+ t=0 0
+ a=tool:idl4k
+ m=video 52780 RTP/AVP 33
+ c=IN IP4 0.0.0.0
+ b=AS:5000
+ a=control:stream=4
+ a=fmtp:33 ver=1.0;tuner=1,0,0,0,12344,h,dvbs2,,off,,22000,34;pids=0,100,101,102,103,106
+ =sendonly
+ */
+
+
+ return response.StatusCode;
+ }
+
+ public RtspStatusCode TearDown()
+ {
+ if ((_rtspSocket == null))
+ {
+ Connect();
+ }
+ //_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
+ RtspResponse response;
+
+ var request = new RtspRequest(RtspMethod.Teardown, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0);
+ request.Headers.Add("Session", _rtspSessionId);
+ SendRequest(request);
+ ReceiveResponse(out response);
+ //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
+ //{
+ // Logger.Error("Failed to tune, non-OK RTSP Teardown status code {0} {1}", response.StatusCode, response.ReasonPhrase);
+ //}
+ return response.StatusCode;
+ }
+
+ #endregion
+
+ #region Public Events
+
+ ////public event PropertyChangedEventHandler PropertyChanged;
+
+ #endregion
+
+ #region Protected Methods
+
+ protected void OnPropertyChanged(string name)
+ {
+ //var handler = PropertyChanged;
+ //if (handler != null)
+ //{
+ // handler(this, new PropertyChangedEventArgs(name));
+ //}
+ }
+
+ #endregion
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);//Disconnect();
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ TearDown();
+ Disconnect();
+ }
+ }
+ _disposed = true;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs
new file mode 100644
index 000000000..6d6d50623
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs
@@ -0,0 +1,251 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+using System.ComponentModel;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp
+{
+ /// <summary>
+ /// Standard RTSP status codes.
+ /// </summary>
+ public enum RtspStatusCode
+ {
+ /// <summary>
+ /// 100 continue
+ /// </summary>
+ Continue = 100,
+
+ /// <summary>
+ /// 200 OK
+ /// </summary>
+ [Description("Okay")]
+ Ok = 200,
+ /// <summary>
+ /// 201 created
+ /// </summary>
+ Created = 201,
+
+ /// <summary>
+ /// 250 low on storage space
+ /// </summary>
+ [Description("Low On Storage Space")]
+ LowOnStorageSpace = 250,
+
+ /// <summary>
+ /// 300 multiple choices
+ /// </summary>
+ [Description("Multiple Choices")]
+ MultipleChoices = 300,
+ /// <summary>
+ /// 301 moved permanently
+ /// </summary>
+ [Description("Moved Permanently")]
+ MovedPermanently = 301,
+ /// <summary>
+ /// 302 moved temporarily
+ /// </summary>
+ [Description("Moved Temporarily")]
+ MovedTemporarily = 302,
+ /// <summary>
+ /// 303 see other
+ /// </summary>
+ [Description("See Other")]
+ SeeOther = 303,
+ /// <summary>
+ /// 304 not modified
+ /// </summary>
+ [Description("Not Modified")]
+ NotModified = 304,
+ /// <summary>
+ /// 305 use proxy
+ /// </summary>
+ [Description("Use Proxy")]
+ UseProxy = 305,
+
+ /// <summary>
+ /// 400 bad request
+ /// </summary>
+ [Description("Bad Request")]
+ BadRequest = 400,
+ /// <summary>
+ /// 401 unauthorised
+ /// </summary>
+ Unauthorised = 401,
+ /// <summary>
+ /// 402 payment required
+ /// </summary>
+ [Description("Payment Required")]
+ PaymentRequired = 402,
+ /// <summary>
+ /// 403 forbidden
+ /// </summary>
+ Forbidden = 403,
+ /// <summary>
+ /// 404 not found
+ /// </summary>
+ [Description("Not Found")]
+ NotFound = 404,
+ /// <summary>
+ /// 405 method not allowed
+ /// </summary>
+ [Description("Method Not Allowed")]
+ MethodNotAllowed = 405,
+ /// <summary>
+ /// 406 not acceptable
+ /// </summary>
+ [Description("Not Acceptable")]
+ NotAcceptable = 406,
+ /// <summary>
+ /// 407 proxy authentication required
+ /// </summary>
+ [Description("Proxy Authentication Required")]
+ ProxyAuthenticationRequred = 407,
+ /// <summary>
+ /// 408 request time-out
+ /// </summary>
+ [Description("Request Time-Out")]
+ RequestTimeOut = 408,
+
+ /// <summary>
+ /// 410 gone
+ /// </summary>
+ Gone = 410,
+ /// <summary>
+ /// 411 length required
+ /// </summary>
+ [Description("Length Required")]
+ LengthRequired = 411,
+ /// <summary>
+ /// 412 precondition failed
+ /// </summary>
+ [Description("Precondition Failed")]
+ PreconditionFailed = 412,
+ /// <summary>
+ /// 413 request entity too large
+ /// </summary>
+ [Description("Request Entity Too Large")]
+ RequestEntityTooLarge = 413,
+ /// <summary>
+ /// 414 request URI too large
+ /// </summary>
+ [Description("Request URI Too Large")]
+ RequestUriTooLarge = 414,
+ /// <summary>
+ /// 415 unsupported media type
+ /// </summary>
+ [Description("Unsupported Media Type")]
+ UnsupportedMediaType = 415,
+
+ /// <summary>
+ /// 451 parameter not understood
+ /// </summary>
+ [Description("Parameter Not Understood")]
+ ParameterNotUnderstood = 451,
+ /// <summary>
+ /// 452 conference not found
+ /// </summary>
+ [Description("Conference Not Found")]
+ ConferenceNotFound = 452,
+ /// <summary>
+ /// 453 not enough bandwidth
+ /// </summary>
+ [Description("Not Enough Bandwidth")]
+ NotEnoughBandwidth = 453,
+ /// <summary>
+ /// 454 session not found
+ /// </summary>
+ [Description("Session Not Found")]
+ SessionNotFound = 454,
+ /// <summary>
+ /// 455 method not valid in this state
+ /// </summary>
+ [Description("Method Not Valid In This State")]
+ MethodNotValidInThisState = 455,
+ /// <summary>
+ /// 456 header field not valid for this resource
+ /// </summary>
+ [Description("Header Field Not Valid For This Resource")]
+ HeaderFieldNotValidForThisResource = 456,
+ /// <summary>
+ /// 457 invalid range
+ /// </summary>
+ [Description("Invalid Range")]
+ InvalidRange = 457,
+ /// <summary>
+ /// 458 parameter is read-only
+ /// </summary>
+ [Description("Parameter Is Read-Only")]
+ ParameterIsReadOnly = 458,
+ /// <summary>
+ /// 459 aggregate operation not allowed
+ /// </summary>
+ [Description("Aggregate Operation Not Allowed")]
+ AggregateOperationNotAllowed = 459,
+ /// <summary>
+ /// 460 only aggregate operation allowed
+ /// </summary>
+ [Description("Only Aggregate Operation Allowed")]
+ OnlyAggregateOperationAllowed = 460,
+ /// <summary>
+ /// 461 unsupported transport
+ /// </summary>
+ [Description("Unsupported Transport")]
+ UnsupportedTransport = 461,
+ /// <summary>
+ /// 462 destination unreachable
+ /// </summary>
+ [Description("Destination Unreachable")]
+ DestinationUnreachable = 462,
+
+ /// <summary>
+ /// 500 internal server error
+ /// </summary>
+ [Description("Internal Server Error")]
+ InternalServerError = 500,
+ /// <summary>
+ /// 501 not implemented
+ /// </summary>
+ [Description("Not Implemented")]
+ NotImplemented = 501,
+ /// <summary>
+ /// 502 bad gateway
+ /// </summary>
+ [Description("Bad Gateway")]
+ BadGateway = 502,
+ /// <summary>
+ /// 503 service unavailable
+ /// </summary>
+ [Description("Service Unavailable")]
+ ServiceUnavailable = 503,
+ /// <summary>
+ /// 504 gateway time-out
+ /// </summary>
+ [Description("Gateway Time-Out")]
+ GatewayTimeOut = 504,
+ /// <summary>
+ /// 505 RTSP version not supported
+ /// </summary>
+ [Description("RTSP Version Not Supported")]
+ RtspVersionNotSupported = 505,
+
+ /// <summary>
+ /// 551 option not supported
+ /// </summary>
+ [Description("Option Not Supported")]
+ OptionNotSupported = 551
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
new file mode 100644
index 000000000..8ecdca46b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs
@@ -0,0 +1,348 @@
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Model.LiveTv;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Extensions;
+using System.Xml.Linq;
+using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Events;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
+{
+ public class SatIpDiscovery : IServerEntryPoint
+ {
+ private readonly IDeviceDiscovery _deviceDiscovery;
+ private readonly IServerConfigurationManager _config;
+ private readonly ILogger _logger;
+ private readonly ILiveTvManager _liveTvManager;
+ private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
+ private readonly IHttpClient _httpClient;
+ private readonly IJsonSerializer _json;
+ private int _tunerCountDVBS=0;
+ private int _tunerCountDVBC=0;
+ private int _tunerCountDVBT=0;
+ private bool _supportsDVBS=false;
+ private bool _supportsDVBC=false;
+ private bool _supportsDVBT=false;
+ public static SatIpDiscovery Current;
+
+ public SatIpDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient, IJsonSerializer json)
+ {
+ _deviceDiscovery = deviceDiscovery;
+ _config = config;
+ _logger = logger;
+ _liveTvManager = liveTvManager;
+ _httpClient = httpClient;
+ _json = json;
+ Current = this;
+ }
+
+ public void Run()
+ {
+ _deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
+ }
+
+ void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e)
+ {
+ var info = e.Argument;
+
+ string st = null;
+ string nt = null;
+ info.Headers.TryGetValue("ST", out st);
+ info.Headers.TryGetValue("NT", out nt);
+
+ if (string.Equals(st, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(nt, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase))
+ {
+ string location;
+ if (info.Headers.TryGetValue("Location", out location) && !string.IsNullOrWhiteSpace(location))
+ {
+ _logger.Debug("SAT IP found at {0}", location);
+
+ // Just get the beginning of the url
+ Uri uri;
+ if (Uri.TryCreate(location, UriKind.Absolute, out uri))
+ {
+ var apiUrl = location.Replace(uri.LocalPath, String.Empty, StringComparison.OrdinalIgnoreCase)
+ .TrimEnd('/');
+
+ AddDevice(apiUrl, location);
+ }
+ }
+ }
+ }
+
+ private async void AddDevice(string deviceUrl, string infoUrl)
+ {
+ await _semaphore.WaitAsync().ConfigureAwait(false);
+
+ try
+ {
+ var options = GetConfiguration();
+
+ if (options.TunerHosts.Any(i => string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) && UriEquals(i.Url, deviceUrl)))
+ {
+ return;
+ }
+
+ _logger.Debug("Will attempt to add SAT device {0}", deviceUrl);
+ var info = await GetInfo(infoUrl, CancellationToken.None).ConfigureAwait(false);
+
+ var existing = GetConfiguration().TunerHosts
+ .FirstOrDefault(i => string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) && string.Equals(i.DeviceId, info.DeviceId, StringComparison.OrdinalIgnoreCase));
+
+ if (existing == null)
+ {
+ //if (string.IsNullOrWhiteSpace(info.M3UUrl))
+ //{
+ // return;
+ //}
+
+ await _liveTvManager.SaveTunerHost(new TunerHostInfo
+ {
+ Type = SatIpHost.DeviceType,
+ Url = deviceUrl,
+ InfoUrl = infoUrl,
+ DataVersion = 1,
+ DeviceId = info.DeviceId,
+ FriendlyName = info.FriendlyName,
+ Tuners = info.Tuners,
+ M3UUrl = info.M3UUrl,
+ IsEnabled = true
+
+ }, true).ConfigureAwait(false);
+ }
+ else
+ {
+ existing.Url = deviceUrl;
+ existing.InfoUrl = infoUrl;
+ existing.M3UUrl = info.M3UUrl;
+ existing.FriendlyName = info.FriendlyName;
+ existing.Tuners = info.Tuners;
+ await _liveTvManager.SaveTunerHost(existing, false).ConfigureAwait(false);
+ }
+ }
+ catch (OperationCanceledException)
+ {
+
+ }
+ catch (NotImplementedException)
+ {
+
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error saving device", ex);
+ }
+ finally
+ {
+ _semaphore.Release();
+ }
+ }
+
+ private bool UriEquals(string savedUri, string location)
+ {
+ return string.Equals(NormalizeUrl(location), NormalizeUrl(savedUri), StringComparison.OrdinalIgnoreCase);
+ }
+
+ private string NormalizeUrl(string url)
+ {
+ if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ url = "http://" + url;
+ }
+
+ url = url.TrimEnd('/');
+
+ // Strip off the port
+ return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped);
+ }
+
+ private LiveTvOptions GetConfiguration()
+ {
+ return _config.GetConfiguration<LiveTvOptions>("livetv");
+ }
+
+ public void Dispose()
+ {
+ }
+ private void ReadCapability(string capability)
+ {
+
+ string[] cap = capability.Split('-');
+ switch (cap[0].ToLower())
+ {
+ case "dvbs":
+ case "dvbs2":
+ {
+ // Optional that you know what an device Supports can you add an flag
+ _supportsDVBS = true;
+
+ for (int i = 0; i < int.Parse(cap[1]); i++)
+ {
+ //ToDo Create Digital Recorder / Tuner Capture Instance here for each with index FE param in Sat>Ip Spec for direct communication with this instance
+ }
+ _tunerCountDVBS = int.Parse(cap[1]);
+ break;
+ }
+ case "dvbc":
+ case "dvbc2":
+ {
+ // Optional that you know what an device Supports can you add an flag
+ _supportsDVBC = true;
+
+ for (int i = 0; i < int.Parse(cap[1]); i++)
+ {
+ //ToDo Create Digital Recorder / Tuner Capture Instance here for each with index FE param in Sat>Ip Spec for direct communication with this instance
+
+ }
+ _tunerCountDVBC = int.Parse(cap[1]);
+ break;
+ }
+ case "dvbt":
+ case "dvbt2":
+ {
+ // Optional that you know what an device Supports can you add an flag
+ _supportsDVBT = true;
+
+
+ for (int i = 0; i < int.Parse(cap[1]); i++)
+ {
+ //ToDo Create Digital Recorder / Tuner Capture Instance here for each with index FE param in Sat>Ip Spec for direct communication with this instance
+
+ }
+ _tunerCountDVBT = int.Parse(cap[1]);
+ break;
+ }
+ }
+
+ }
+ public async Task<SatIpTunerHostInfo> GetInfo(string url, CancellationToken cancellationToken)
+ {
+ Uri locationUri = new Uri(url);
+ string devicetype = "";
+ string friendlyname = "";
+ string uniquedevicename = "";
+ string manufacturer = "";
+ string manufacturerurl = "";
+ string modelname = "";
+ string modeldescription = "";
+ string modelnumber = "";
+ string modelurl = "";
+ string serialnumber = "";
+ string presentationurl = "";
+ //string capabilities = "";
+ string m3u = "";
+ var document = XDocument.Load(locationUri.AbsoluteUri);
+ var xnm = new XmlNamespaceManager(new NameTable());
+ XNamespace n1 = "urn:ses-com:satip";
+ XNamespace n0 = "urn:schemas-upnp-org:device-1-0";
+ xnm.AddNamespace("root", n0.NamespaceName);
+ xnm.AddNamespace("satip:", n1.NamespaceName);
+ if (document.Root != null)
+ {
+ var deviceElement = document.Root.Element(n0 + "device");
+ if (deviceElement != null)
+ {
+ var devicetypeElement = deviceElement.Element(n0 + "deviceType");
+ if (devicetypeElement != null)
+ devicetype = devicetypeElement.Value;
+ var friendlynameElement = deviceElement.Element(n0 + "friendlyName");
+ if (friendlynameElement != null)
+ friendlyname = friendlynameElement.Value;
+ var manufactureElement = deviceElement.Element(n0 + "manufacturer");
+ if (manufactureElement != null)
+ manufacturer = manufactureElement.Value;
+ var manufactureurlElement = deviceElement.Element(n0 + "manufacturerURL");
+ if (manufactureurlElement != null)
+ manufacturerurl = manufactureurlElement.Value;
+ var modeldescriptionElement = deviceElement.Element(n0 + "modelDescription");
+ if (modeldescriptionElement != null)
+ modeldescription = modeldescriptionElement.Value;
+ var modelnameElement = deviceElement.Element(n0 + "modelName");
+ if (modelnameElement != null)
+ modelname = modelnameElement.Value;
+ var modelnumberElement = deviceElement.Element(n0 + "modelNumber");
+ if (modelnumberElement != null)
+ modelnumber = modelnumberElement.Value;
+ var modelurlElement = deviceElement.Element(n0 + "modelURL");
+ if (modelurlElement != null)
+ modelurl = modelurlElement.Value;
+ var serialnumberElement = deviceElement.Element(n0 + "serialNumber");
+ if (serialnumberElement != null)
+ serialnumber = serialnumberElement.Value;
+ var uniquedevicenameElement = deviceElement.Element(n0 + "UDN");
+ if (uniquedevicenameElement != null) uniquedevicename = uniquedevicenameElement.Value;
+ var presentationUrlElement = deviceElement.Element(n0 + "presentationURL");
+ if (presentationUrlElement != null) presentationurl = presentationUrlElement.Value;
+ var capabilitiesElement = deviceElement.Element(n1 + "X_SATIPCAP");
+ if (capabilitiesElement != null)
+ {
+ //_capabilities = capabilitiesElement.Value;
+ if (capabilitiesElement.Value.Contains(','))
+ {
+ string[] capabilities = capabilitiesElement.Value.Split(',');
+ foreach (var capability in capabilities)
+ {
+ ReadCapability(capability);
+ }
+ }
+ else
+ {
+ ReadCapability(capabilitiesElement.Value);
+ }
+ }
+ else
+ {
+ _supportsDVBS = true;
+ _tunerCountDVBS =1;
+ }
+ var m3uElement = deviceElement.Element(n1 + "X_SATIPM3U");
+ if (m3uElement != null) m3u = m3uElement.Value;
+ }
+ }
+
+ var result = new SatIpTunerHostInfo
+ {
+ Url = url,
+ Id = uniquedevicename,
+ IsEnabled = true,
+ Type = SatIpHost.DeviceType,
+ Tuners = _tunerCountDVBS,
+ TunersAvailable = _tunerCountDVBS,
+ M3UUrl = m3u
+ };
+
+ result.FriendlyName = friendlyname;
+ if (string.IsNullOrWhiteSpace(result.Id))
+ {
+ throw new NotImplementedException();
+ }
+
+ else if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ var fullM3uUrl = url.Substring(0, url.LastIndexOf('/'));
+ result.M3UUrl = fullM3uUrl + "/" + result.M3UUrl.TrimStart('/');
+ }
+
+ _logger.Debug("SAT device result: {0}", _json.SerializeToString(result));
+
+ return result;
+ }
+ }
+
+ public class SatIpTunerHostInfo : TunerHostInfo
+ {
+ public int TunersAvailable { get; set; }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
new file mode 100644
index 000000000..55101ce10f
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Emby.Server.Implementations.LiveTv.TunerHosts;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.LiveTv;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Serialization;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
+{
+ public class SatIpHost : BaseTunerHost, ITunerHost
+ {
+ private readonly IFileSystem _fileSystem;
+ private readonly IHttpClient _httpClient;
+ private readonly IServerApplicationHost _appHost;
+
+ public SatIpHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
+ : base(config, logger, jsonSerializer, mediaEncoder)
+ {
+ _fileSystem = fileSystem;
+ _httpClient = httpClient;
+ _appHost = appHost;
+ }
+
+ private const string ChannelIdPrefix = "sat_";
+
+ protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken)
+ {
+ if (!string.IsNullOrWhiteSpace(tuner.M3UUrl))
+ {
+ return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
+ }
+
+ var channels = await new ChannelScan(Logger).Scan(tuner, cancellationToken).ConfigureAwait(false);
+ return channels;
+ }
+
+ public static string DeviceType
+ {
+ get { return "satip"; }
+ }
+
+ public override string Type
+ {
+ get { return DeviceType; }
+ }
+
+ protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+ {
+ var urlHash = tuner.Url.GetMD5().ToString("N");
+ var prefix = ChannelIdPrefix + urlHash;
+ if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
+ {
+ return null;
+ }
+
+ var channels = await GetChannels(tuner, true, cancellationToken).ConfigureAwait(false);
+ var m3uchannels = channels.Cast<M3UChannel>();
+ var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase));
+ if (channel != null)
+ {
+ var path = channel.Path;
+ MediaProtocol protocol = MediaProtocol.File;
+ if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Http;
+ }
+ else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtmp;
+ }
+ else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase))
+ {
+ protocol = MediaProtocol.Rtsp;
+ }
+
+ var mediaSource = new MediaSourceInfo
+ {
+ Path = channel.Path,
+ Protocol = protocol,
+ MediaStreams = new List<MediaStream>
+ {
+ new MediaStream
+ {
+ Type = MediaStreamType.Video,
+ // Set the index to -1 because we don't know the exact index of the video stream within the container
+ Index = -1,
+ IsInterlaced = true
+ },
+ new MediaStream
+ {
+ Type = MediaStreamType.Audio,
+ // Set the index to -1 because we don't know the exact index of the audio stream within the container
+ Index = -1
+
+ }
+ },
+ RequiresOpening = false,
+ RequiresClosing = false
+ };
+
+ return new List<MediaSourceInfo> { mediaSource };
+ }
+ return new List<MediaSourceInfo>();
+ }
+
+ protected override async Task<LiveStream> GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken)
+ {
+ var sources = await GetChannelStreamMediaSources(tuner, channelId, cancellationToken).ConfigureAwait(false);
+
+ var liveStream = new LiveStream(sources.First());
+
+ return liveStream;
+ }
+
+ protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+ {
+ var updatedInfo = await SatIpDiscovery.Current.GetInfo(tuner.InfoUrl, cancellationToken).ConfigureAwait(false);
+
+ return updatedInfo.TunersAvailable > 0;
+ }
+
+ protected override bool IsValidChannelId(string channelId)
+ {
+ return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public string Name
+ {
+ get { return "Sat IP"; }
+ }
+
+ public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)
+ {
+ var list = GetTunerHosts()
+ .SelectMany(i => GetTunerInfos(i, cancellationToken))
+ .ToList();
+
+ return Task.FromResult(list);
+ }
+
+ public List<LiveTvTunerInfo> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken)
+ {
+ var list = new List<LiveTvTunerInfo>();
+
+ for (var i = 0; i < info.Tuners; i++)
+ {
+ list.Add(new LiveTvTunerInfo
+ {
+ Name = info.FriendlyName ?? Name,
+ SourceType = Type,
+ Status = LiveTvTunerStatus.Available,
+ Id = info.Url.GetMD5().ToString("N") + i.ToString(CultureInfo.InvariantCulture),
+ Url = info.Url
+ });
+ }
+
+ return list;
+ }
+
+ public string ApplyDuration(string streamPath, TimeSpan duration)
+ {
+ return streamPath;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs
new file mode 100644
index 000000000..71d7656d9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/TransmissionMode.cs
@@ -0,0 +1,25 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
+{
+ public enum TransmissionMode
+ {
+ Unicast,
+ Multicast
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs
new file mode 100644
index 000000000..3595e4b0a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/Utils.cs
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) <2007-2016> <Kay Diefenthal>
+
+ SatIp.RtspSample is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ SatIp.RtspSample is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
+*/
+using System;
+using System.Text;
+
+namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
+{
+ public class Utils
+ {
+ public static int Convert2BytesToInt(byte[] buffer, int offset)
+ {
+ int temp = (int)buffer[offset];
+ temp = (temp * 256) + buffer[offset + 1];
+
+ return (temp);
+ }
+ public static int Convert3BytesToInt(byte[] buffer, int offset)
+ {
+ int temp = (int)buffer[offset];
+ temp = (temp * 256) + buffer[offset + 1];
+ temp = (temp * 256) + buffer[offset + 2];
+
+ return (temp);
+ }
+ public static int Convert4BytesToInt(byte[] buffer, int offset)
+ {
+ int temp =(int)buffer[offset];
+ temp = (temp * 256) + buffer[offset + 1];
+ temp = (temp * 256) + buffer[offset + 2];
+ temp = (temp * 256) + buffer[offset + 3];
+
+ return (temp);
+ }
+ public static long Convert4BytesToLong(byte[] buffer, int offset)
+ {
+ long temp = 0;
+
+ for (int index = 0; index < 4; index++)
+ temp = (temp * 256) + buffer[offset + index];
+
+ return (temp);
+ }
+ public static long Convert8BytesToLong(byte[] buffer, int offset)
+ {
+ long temp = 0;
+
+ for (int index = 0; index < 8; index++)
+ temp = (temp * 256) + buffer[offset + index];
+
+ return (temp);
+ }
+ public static string ConvertBytesToString(byte[] buffer, int offset, int length)
+ {
+ StringBuilder reply = new StringBuilder(4);
+ for (int index = 0; index < length; index++)
+ reply.Append((char)buffer[offset + index]);
+ return (reply.ToString());
+ }
+ public static DateTime NptTimestampToDateTime(long nptTimestamp) { return NptTimestampToDateTime((uint)((nptTimestamp >> 32) & 0xFFFFFFFF), (uint)(nptTimestamp & 0xFFFFFFFF),null); }
+
+ public static DateTime NptTimestampToDateTime(uint seconds, uint fractions, DateTime? epoch )
+ {
+ ulong ticks =(ulong)((seconds * TimeSpan.TicksPerSecond) + ((fractions * TimeSpan.TicksPerSecond) / 0x100000000L));
+ if (epoch.HasValue) return epoch.Value + TimeSpan.FromTicks((Int64)ticks);
+ return (seconds & 0x80000000L) == 0 ? UtcEpoch2036 + TimeSpan.FromTicks((Int64)ticks) : UtcEpoch1900 + TimeSpan.FromTicks((Int64)ticks);
+ }
+
+ //When the First Epoch will wrap (The real Y2k)
+ public static DateTime UtcEpoch2036 = new DateTime(2036, 2, 7, 6, 28, 16, DateTimeKind.Utc);
+
+ public static DateTime UtcEpoch1900 = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ public static DateTime UtcEpoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini
new file mode 100644
index 000000000..1caa948cf
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0030.ini
@@ -0,0 +1,100 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0030
+2=Eutelsat 3B/Rascom QAF 1R (3.0E)
+
+[DVB]
+0=91
+1=3794,H,3590,23,S2,8PSK
+2=3797,H,2442,23,DVB-S,QPSK
+3=3970,V,2741,34,DVB-S,QPSK
+4=3975,V,3111,23,DVB-S,QPSK
+5=3986,V,13557,56,DVB-S,QPSK
+6=4151,V,2141,56,S2,QPSK
+7=4173,V,1917,56,S2,QPSK
+8=10961,H,10000,34,S2,8PSK
+9=10973,H,10000,34,S2,8PSK
+10=10985,H,10000,34,S2,QPSK
+11=11042,H,4279,89,S2,QPSK
+12=11049,H,1000,23,S2,8PSK
+13=11051,H,2100,56,S2,QPSK
+14=11078,H,7430,56,S2,QPSK
+15=11088,H,7430,56,S2,QPSK
+16=11097,H,7430,56,S2,QPSK
+17=11456,V,2876,78,DVB-S,QPSK
+18=11456,H,1480,34,S2,8PSK
+19=11457,H,3000,78,DVB-S,QPSK
+20=11461,V,2000,34,DVB-S,QPSK
+21=11465,V,2500,78,DVB-S,QPSK
+22=11468,H,2963,34,DVB-S,QPSK
+23=11471,V,2500,78,DVB-S,QPSK
+24=11472,H,2600,34,DVB-S,QPSK
+25=11476,H,2600,34,DVB-S,QPSK
+26=11479,V,3000,56,S2,QPSK
+27=11480,H,1480,78,DVB-S,QPSK
+28=11482,V,11852,34,DVB-S,QPSK
+29=11487,H,1480,34,S2,8PSK
+30=11490,H,2222,56,DVB-S,QPSK
+31=11496,H,3000,34,DVB-S,QPSK
+32=11498,V,11852,34,DVB-S,QPSK
+33=11503,H,1480,56,S2,8PSK
+34=11507,H,1480,34,S2,8PSK
+35=11521,H,8800,23,S2,8PSK
+36=11521,V,1500,34,S2,8PSK
+37=11530,V,1500,34,S2,8PSK
+38=11532,V,1500,34,S2,8PSK
+39=11533,H,8800,23,S2,8PSK
+40=11544,H,3550,34,S2,8PSK
+41=11555,H,8800,23,DVB-S,QPSK
+42=11562,H,2850,34,DVB-S,QPSK
+43=11585,H,9600,23,S2,8PSK
+44=11585,V,9260,56,DVB-S,QPSK
+45=11594,V,3333,78,DVB-S,QPSK
+46=11597,H,2250,34,DVB-S,QPSK
+47=11598,V,2250,34,DVB-S,QPSK
+48=11606,V,1480,56,S2,8PSK
+49=11609,H,9600,23,S2,8PSK
+50=11615,V,2200,34,DVB-S,QPSK
+51=11621,H,9600,56,S2,8PSK
+52=11621,V,1200,34,S2,8PSK
+53=11632,V,2200,34,DVB-S,QPSK
+54=11642,H,1111,34,S2,8PSK
+55=11645,H,3000,34,DVB-S,QPSK
+56=11649,H,3000,34,DVB-S,QPSK
+57=11655,H,2304,34,S2,8PSK
+58=11660,H,2400,56,DVB-S,QPSK
+59=11663,H,1550,56,S2,8PSK
+60=11671,V,1500,34,S2,8PSK
+61=11673,V,1500,34,S2,8PSK
+62=11675,V,1500,56,S2,8PSK
+63=11680,V,3750,34,DVB-S,QPSK
+64=11692,V,1860,78,DVB-S,QPSK
+65=11696,V,2000,34,DVB-S,QPSK
+66=12526,H,4444,34,S2,8PSK
+67=12531,H,2265,89,S2,QPSK
+68=12534,H,2500,34,S2,8PSK
+69=12537,H,2500,34,S2,8PSK
+70=12548,V,3000,56,S2,QPSK
+71=12553,V,1100,56,S2,8PSK
+72=12554,V,1100,56,S2,8PSK
+73=12556,V,1100,34,S2,8PSK
+74=12557,V,1500,34,DVB-S,QPSK
+75=12559,V,1500,56,S2,8PSK
+76=12563,V,1500,34,S2,8PSK
+77=12566,V,2750,23,S2,8PSK
+78=12571,V,3650,23,S2,8PSK
+79=12572,H,10000,34,S2,QPSK
+80=12574,V,1447,34,DVB-S,QPSK
+81=12576,V,1570,34,S2,8PSK
+82=12609,H,9600,23,S2,8PSK
+83=12638,V,14400,34,S2,8PSK
+84=12692,H,1450,56,S2,8PSK
+85=12702,H,13960,35,S2,QPSK
+86=12703,V,3704,34,S2,8PSK
+87=12707,V,2963,34,S2,8PSK
+88=12717,V,2143,56,DVB-S,QPSK
+89=12720,H,13960,35,S2,QPSK
+90=12734,V,16750,35,S2,QPSK
+91=12737,H,2930,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini
new file mode 100644
index 000000000..92a0e7dda
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0049.ini
@@ -0,0 +1,102 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0049
+2=Astra 4A/SES 5 (4.9E)
+
+[DVB]
+0=93
+1=3644,H,1300,56,S2,QPSK
+2=3843,V,1055,910,S2,QPSK
+3=3857,V,1520,35,S2,QPSK
+4=3863,V,1130,56,S2,QPSK
+5=3866,V,1400,23,S2,QPSK
+6=3868,V,1203,56,S2,QPSK
+7=3871,V,1550,23,S2,QPSK
+8=3876,V,6200,23,S2,QPSK
+9=11265,H,30000,34,S2,8PSK
+10=11265,V,30000,34,S2,8PSK
+11=11305,H,30000,34,S2,8PSK
+12=11305,V,30000,34,S2,8PSK
+13=11345,H,30000,34,S2,8PSK
+14=11345,V,30000,34,S2,8PSK
+15=11385,V,30000,34,S2,8PSK
+16=11727,H,27500,56,DVB-S,QPSK
+17=11747,V,27500,23,S2,QPSK
+18=11766,H,27500,34,DVB-S,QPSK
+19=11785,V,27500,56,DVB-S,8PSK
+20=11804,H,27500,34,DVB-S,QPSK
+21=11823,V,27500,34,DVB-S,QPSK
+22=11843,H,27500,34,DVB-S,QPSK
+23=11862,V,27500,34,DVB-S,8PSK
+24=11881,H,27500,34,DVB-S,QPSK
+25=11900,V,27500,34,DVB-S,QPSK
+26=11919,H,27500,34,DVB-S,QPSK
+27=11938,V,27500,34,DVB-S,8PSK
+28=11958,H,27500,34,DVB-S,QPSK
+29=11977,V,27500,34,DVB-S,8PSK
+30=11996,H,27500,34,DVB-S,8PSK
+31=12015,V,27500,56,DVB-S,QPSK
+32=12034,H,27500,34,DVB-S,QPSK
+33=12054,V,27500,34,DVB-S,QPSK
+34=12073,H,27500,34,DVB-S,8PSK
+35=12092,V,27500,34,DVB-S,QPSK
+36=12111,H,27500,56,DVB-S,QPSK
+37=12130,V,27500,34,DVB-S,QPSK
+38=12149,H,27500,34,DVB-S,QPSK
+39=12169,V,27500,34,S2,8PSK
+40=12188,H,30000,34,S2,8PSK
+41=12207,V,30000,34,S2,8PSK
+42=12245,V,27500,34,DVB-S,QPSK
+43=12284,V,27500,34,DVB-S,QPSK
+44=12303,H,25546,78,DVB-S,8PSK
+45=12322,V,27500,56,S2,QPSK
+46=12341,H,30000,34,S2,8PSK
+47=12360,V,27500,56,S2,8PSK
+48=12380,H,27500,34,DVB-S,8PSK
+49=12399,V,27500,34,DVB-S,QPSK
+50=12418,H,27500,34,DVB-S,8PSK
+51=12437,V,27500,34,S2,8PSK
+52=12476,V,27500,34,DVB-S,QPSK
+53=12514,H,6111,34,DVB-S,QPSK
+54=12515,V,7200,34,S2,8PSK
+55=12519,H,4610,34,S2,8PSK
+56=12524,V,7200,34,S2,8PSK
+57=12528,H,9874,34,S2,8PSK
+58=12538,V,4610,34,S2,8PSK
+59=12540,H,3750,23,S2,8PSK
+60=12543,V,4610,34,S2,8PSK
+61=12551,V,7400,34,S2,8PSK
+62=12560,V,7200,34,S2,8PSK
+63=12580,V,3829,34,DVB-S,QPSK
+64=12593,V,7200,34,S2,8PSK
+65=12602,V,6111,34,DVB-S,QPSK
+66=12608,H,27500,34,DVB-S,QPSK
+67=12612,V,6111,34,DVB-S,QPSK
+68=12620,V,6111,34,DVB-S,QPSK
+69=12621,V,3660,23,DVB-S,QPSK
+70=12637,H,14468,34,DVB-S,QPSK
+71=12670,H,2600,23,DVB-S,QPSK
+72=12671,V,3333,34,DVB-S,QPSK
+73=12673,H,3750,35,S2,8PSK
+74=12674,V,3333,34,DVB-S,QPSK
+75=12678,H,6666,78,DVB-S,QPSK
+76=12694,H,6666,34,DVB-S,QPSK
+77=12694,V,3333,56,DVB-S,QPSK
+78=12699,H,3040,78,DVB-S,QPSK
+79=12702,V,3333,34,DVB-S,QPSK
+80=12702,H,2100,34,S2,8PSK
+81=12710,V,4430,34,DVB-S,QPSK
+82=12712,H,5000,78,DVB-S,QPSK
+83=12716,V,4430,34,DVB-S,QPSK
+84=12719,H,2960,34,DVB-S,QPSK
+85=12719,V,2950,34,DVB-S,QPSK
+86=12722,V,4430,34,DVB-S,QPSK
+87=12725,V,1480,89,S2,8PSK
+88=12728,V,4430,34,DVB-S,QPSK
+89=12730,V,2960,34,DVB-S,QPSK
+90=12733,H,3400,34,DVB-S,QPSK
+91=12734,V,4430,34,DVB-S,8PSK
+92=12737,H,3472,34,DVB-S,QPSK
+93=12740,V,4430,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini
new file mode 100644
index 000000000..800b097c8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0070.ini
@@ -0,0 +1,134 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0070
+2=Eutelsat 7A/7B (7.0E)
+
+[DVB]
+0=125
+1=10721,H,22000,34,DVB-S,8PSK
+2=10721,V,27500,34,DVB-S,QPSK
+3=10762,V,30000,34,DVB-S,QPSK
+4=10804,H,30000,56,S2,QPSK
+5=10804,V,29900,34,DVB-S,QPSK
+6=10845,H,30000,56,S2,QPSK
+7=10845,V,30000,34,DVB-S,QPSK
+8=10887,H,30000,34,S2,QPSK
+9=10887,V,30000,56,S2,QPSK
+10=10928,H,30000,34,S2,8PSK
+11=10928,V,30000,56,S2,QPSK
+12=10958,V,4936,34,S2,8PSK
+13=10959,H,4936,34,S2,8PSK
+14=10962,H,3255,23,DVB-S,QPSK
+15=10970,V,4434,78,DVB-S,QPSK
+16=10971,H,4936,34,S2,8PSK
+17=10976,H,4936,34,S2,8PSK
+18=10978,V,7200,34,S2,8PSK
+19=10987,H,4936,34,S2,8PSK
+20=10994,V,4936,34,S2,8PSK
+21=10997,H,9874,34,S2,8PSK
+22=10999,H,3209,Auto,DVB-S,QPSK
+23=11000,V,4936,34,S2,8PSK
+24=11006,V,4936,34,S2,8PSK
+25=11009,H,9874,34,S2,8PSK
+26=11012,V,4936,34,S2,8PSK
+27=11014,H,6111,Auto,DVB-S,QPSK
+28=11018,V,3255,78,DVB-S,QPSK
+29=11021,H,9874,34,S2,8PSK
+30=11022,V,3676,34,S2,8PSK
+31=11023,H,6111,Auto,S2,QPSK
+32=11042,V,4936,34,S2,8PSK
+33=11046,H,8335,56,S2,8PSK
+34=11048,V,14400,34,S2,8PSK
+35=11054,H,4936,34,S2,8PSK
+36=11057,V,9874,34,S2,8PSK
+37=11059,H,14238,56,S2,QPSK
+38=11060,H,4936,34,S2,8PSK
+39=11066,H,4936,34,S2,8PSK
+40=11068,V,9874,34,S2,8PSK
+41=11080,V,9874,34,S2,8PSK
+42=11084,H,4936,34,S2,8PSK
+43=11090,H,4936,34,S2,8PSK
+44=11090,V,4936,34,S2,8PSK
+45=11096,H,4936,34,S2,8PSK
+46=11102,H,14400,34,S2,8PSK
+47=11105,H,4340,34,DVB-S,QPSK
+48=11107,V,7200,34,S2,8PSK
+49=11124,V,3600,34,S2,8PSK
+50=11128,H,9874,34,S2,8PSK
+51=11128,V,3750,34,S2,8PSK
+52=11134,V,5000,34,S2,8PSK
+53=11137,H,4936,34,S2,8PSK
+54=11140,V,9600,34,S2,8PSK
+55=11143,H,4936,34,S2,8PSK
+56=11148,H,4936,34,S2,8PSK
+57=11153,V,7200,34,S2,8PSK
+58=11154,H,4936,34,S2,8PSK
+59=11160,H,3254,56,S2,8PSK
+60=11161,V,4936,34,S2,8PSK
+61=11164,H,3255,34,S2,8PSK
+62=11165,V,3204,34,DVB-S,QPSK
+63=11171,H,7500,56,S2,8PSK
+64=11173,V,3674,34,S2,8PSK
+65=11181,V,7442,34,S2,8PSK
+66=11184,H,5714,Auto,DVB-S,QPSK
+67=11186,V,3255,34,DVB-S,QPSK
+68=11192,H,3210,34,DVB-S,QPSK
+69=11192,V,3700,34,S2,8PSK
+70=11221,H,27500,34,DVB-S,QPSK
+71=11262,H,27500,56,DVB-S,QPSK
+72=11356,H,45000,56,S2,QPSK
+73=11387,H,27500,34,DVB-S,QPSK
+74=11418,H,45000,56,S2,QPSK
+75=11456,V,20050,34,DVB-S,QPSK
+76=11471,H,30000,34,DVB-S,QPSK
+77=11492,V,30000,34,DVB-S,QPSK
+78=11513,H,29900,34,DVB-S,QPSK
+79=11534,V,30000,34,DVB-S,QPSK
+80=11554,H,30000,34,DVB-S,QPSK
+81=11575,V,30000,34,DVB-S,QPSK
+82=11596,H,30000,34,DVB-S,QPSK
+83=11617,V,30000,34,DVB-S,QPSK
+84=11668,V,30000,56,S2,QPSK
+85=11678,H,30000,34,DVB-S,QPSK
+86=12510,H,7120,34,S2,8PSK
+87=12519,H,6144,34,S2,8PSK
+88=12520,V,9800,34,S2,8PSK
+89=12532,V,1852,23,S2,QPSK
+90=12545,H,4950,34,S2,8PSK
+91=12548,V,3650,34,S2,8PSK
+92=12555,H,4830,78,DVB-S,8PSK
+93=12556,V,4035,56,S2,8PSK
+94=12565,H,6750,23,S2,8PSK
+95=12573,H,7120,34,S2,8PSK
+96=12596,V,2500,34,S2,8PSK
+97=12603,H,30000,23,S2,8PSK
+98=12603,V,2500,34,S2,8PSK
+99=12606,V,2500,34,S2,8PSK
+100=12611,V,5000,34,S2,8PSK
+101=12615,V,2500,34,S2,8PSK
+102=12619,V,4444,78,DVB-S,QPSK
+103=12624,V,2500,34,S2,8PSK
+104=12627,V,2500,34,S2,8PSK
+105=12630,V,2500,34,S2,8PSK
+106=12643,V,6430,23,S2,8PSK
+107=12645,H,30000,23,S2,8PSK
+108=12650,V,2400,34,S2,8PSK
+109=12653,V,2400,56,S2,8PSK
+110=12659,V,4936,34,S2,8PSK
+111=12675,H,6430,23,S2,8PSK
+112=12687,H,6975,56,S2,8PSK
+113=12695,V,6666,78,DVB-S,8PSK
+114=12701,H,4800,34,S2,8PSK
+115=12704,V,7500,34,S2,8PSK
+116=12711,V,4936,34,S2,8PSK
+117=12727,V,10000,34,S2,8PSK
+118=12728,H,30000,56,DVB-S,QPSK
+119=12740,V,6111,34,DVB-S,QPSK
+120=21439,H,6111,34,DVB-S,QPSK
+121=21553,H,9600,56,S2,8PSK
+122=21565,H,1571,78,DVB-S,QPSK
+123=21571,H,2442,23,DVB-S,QPSK
+124=21584,H,1100,34,S2,8PSK
+125=21603,H,6428,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini
new file mode 100644
index 000000000..6202569d9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0090.ini
@@ -0,0 +1,40 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0090
+2=Eutelsat 9A/Ka-Sat 9A (9.0E)
+
+[DVB]
+0=31
+1=11727,V,27500,34,DVB-S,QPSK
+2=11747,H,27500,23,S2,8PSK
+3=11766,V,27500,34,DVB-S,QPSK
+4=11785,H,27500,23,S2,8PSK
+5=11804,V,27500,34,DVB-S,QPSK
+6=11823,H,27500,34,DVB-S,QPSK
+7=11843,V,27500,35,S2,8PSK
+8=11861,H,27500,23,S2,8PSK
+9=11881,V,27500,23,S2,8PSK
+10=11900,H,27500,23,S2,8PSK
+11=11919,V,27500,34,DVB-S,QPSK
+12=11938,H,27500,34,DVB-S,QPSK
+13=11958,V,27500,23,S2,8PSK
+14=11996,V,27500,34,DVB-S,QPSK
+15=12015,H,27500,23,S2,8PSK
+16=12034,V,27500,34,S2,8PSK
+17=12054,H,27500,23,S2,8PSK
+18=12074,V,27500,34,S2,8PSK
+19=12092,H,27500,34,S2,8PSK
+20=12130,H,27500,34,DVB-S,QPSK
+21=12149,V,27500,23,S2,8PSK
+22=12226,V,27500,23,S2,8PSK
+23=12265,V,27500,23,S2,8PSK
+24=12284,H,27500,23,S2,8PSK
+25=12322,H,27500,34,DVB-S,QPSK
+26=12360,H,27500,23,S2,8PSK
+27=12380,V,27500,23,S2,8PSK
+28=12399,H,27500,23,S2,8PSK
+29=12418,V,27500,23,S2,8PSK
+30=12437,H,27500,23,S2,8PSK
+31=20185,H,25000,23,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini
new file mode 100644
index 000000000..0614ba88c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0100.ini
@@ -0,0 +1,206 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0100
+2=Eutelsat 10A (10.0E)
+
+[DVB]
+0=197
+1=3649,H,20160,23,S2,QPSK
+2=3706,V,6250,56,S2,8PSK
+3=3708,H,1002,56,S2,8PSK
+4=3721,V,3303,56,S2,8PSK
+5=3729,V,10321,56,S2,8PSK
+6=3741,V,10114,56,S2,8PSK
+7=3759,V,19816,56,S2,8PSK
+8=3781,V,16445,56,S2,8PSK
+9=3827,V,3080,34,S2,8PSK
+10=3835,V,1000,45,S2,QPSK
+11=3837,V,1185,34,S2,8PSK
+12=3839,V,1185,34,S2,8PSK
+13=3865,V,13333,78,DVB-S,QPSK
+14=3956,V,1500,23,DVB-S,QPSK
+15=4039,V,2222,34,S2,8PSK
+16=10707,V,3100,34,DVB-S,QPSK
+17=10712,V,4167,56,DVB-S,QPSK
+18=10717,V,3215,34,DVB-S,QPSK
+19=10734,V,1447,34,DVB-S,QPSK
+20=10738,V,2894,34,DVB-S,QPSK
+21=10742,V,2894,34,DVB-S,QPSK
+22=10747,V,4000,910,S2,8PSK
+23=10756,V,2480,78,DVB-S,QPSK
+24=10792,V,4936,34,S2,QPSK
+25=10798,V,4936,34,S2,8PSK
+26=10803,V,6111,34,DVB-S,QPSK
+27=10810,V,4430,34,DVB-S,QPSK
+28=10822,V,4430,34,S2,8PSK
+29=10832,V,8876,56,S2,8PSK
+30=10840,V,3255,12,DVB-S,QPSK
+31=10848,V,6111,34,DVB-S,QPSK
+32=10859,V,2875,Auto,S2,QPSK
+33=10877,V,6111,34,DVB-S,QPSK
+34=10886,V,6111,Auto,DVB-S,QPSK
+35=10893,V,4936,34,S2,QPSK
+36=10899,V,4936,34,S2,8PSK
+37=10905,V,4936,34,S2,QPSK
+38=10918,V,4430,34,DVB-S,QPSK
+39=10923,V,4600,56,S2,8PSK
+40=10931,V,7120,34,S2,8PSK
+41=10940,V,6080,34,DVB-S,QPSK
+42=10956,H,2500,56,DVB-S,QPSK
+43=10960,V,4167,56,DVB-S,QPSK
+44=10965,H,3124,34,DVB-S,QPSK
+45=10965,V,4167,56,DVB-S,QPSK
+46=10969,H,3124,34,DVB-S,QPSK
+47=10970,V,4167,56,DVB-S,QPSK
+48=10973,H,3124,34,DVB-S,QPSK
+49=10976,V,4167,56,DVB-S,QPSK
+50=10977,H,3124,34,DVB-S,QPSK
+51=10981,H,3124,34,DVB-S,QPSK
+52=10981,V,4600,56,S2,8PSK
+53=10985,H,3124,34,DVB-S,QPSK
+54=10988,H,3124,34,DVB-S,QPSK
+55=10992,H,3124,34,DVB-S,QPSK
+56=10998,V,2900,34,DVB-S,QPSK
+57=11004,V,2400,34,DVB-S,QPSK
+58=11005,H,7120,34,S2,8PSK
+59=11008,V,2963,34,DVB-S,QPSK
+60=11014,H,7120,34,S2,8PSK
+61=11018,V,2857,34,DVB-S,QPSK
+62=11022,V,2650,34,DVB-S,QPSK
+63=11023,H,7120,34,S2,8PSK
+64=11043,H,7120,23,S2,8PSK
+65=11060,H,4937,34,S2,8PSK
+66=11066,H,4937,34,S2,8PSK
+67=11074,H,4937,34,S2,8PSK
+68=11075,V,68571,34,DVB-S,QPSK
+69=11093,H,9874,34,S2,8PSK
+70=11107,H,4936,34,S2,8PSK
+71=11124,H,3300,34,DVB-S,8PSK
+72=11127,V,6111,34,DVB-S,QPSK
+73=11129,H,3333,34,DVB-S,8PSK
+74=11134,H,3333,34,DVB-S,QPSK
+75=11136,V,7400,34,S2,8PSK
+76=11138,H,2400,56,S2,8PSK
+77=11144,H,6111,34,DVB-S,QPSK
+78=11144,V,6666,78,DVB-S,QPSK
+79=11151,H,3254,34,DVB-S,QPSK
+80=11154,V,5632,34,DVB-S,QPSK
+81=11160,H,2267,56,S2,8PSK
+82=11162,V,2400,34,DVB-S,QPSK
+83=11165,H,3750,34,S2,8PSK
+84=11168,V,2300,34,DVB-S,QPSK
+85=11169,H,3028,34,S2,QPSK
+86=11173,H,3028,34,S2,QPSK
+87=11179,H,2066,23,S2,8PSK
+88=11182,H,2400,23,S2,8PSK
+89=11186,H,2667,56,DVB-S,QPSK
+90=11189,H,2352,34,DVB-S,QPSK
+91=11193,H,2880,34,S2,QPSK
+92=11207,H,7500,34,S2,8PSK
+93=11221,V,30000,56,S2,QPSK
+94=11291,H,9875,34,S2,8PSK
+95=11294,V,14400,34,S2,8PSK
+96=11317,H,7500,56,S2,8PSK
+97=11346,H,27500,34,DVB-S,QPSK
+98=11375,V,9874,34,S2,8PSK
+99=11399,V,9874,34,S2,8PSK
+100=11419,H,11814,56,S2,8PSK
+101=11434,H,10098,35,S2,QPSK
+102=11457,H,6111,34,DVB-S,QPSK
+103=11483,V,4000,56,S2,8PSK
+104=11488,H,2100,34,DVB-S,QPSK
+105=11498,V,7450,34,S2,8PSK
+106=11501,H,2894,34,DVB-S,QPSK
+107=11505,H,3000,34,DVB-S,QPSK
+108=11509,H,3000,34,DVB-S,QPSK
+109=11511,V,3324,34,DVB-S,QPSK
+110=11515,V,4200,34,DVB-S,QPSK
+111=11520,V,4200,34,DVB-S,QPSK
+112=11524,H,2810,34,DVB-S,QPSK
+113=11525,V,4167,56,DVB-S,QPSK
+114=11528,H,2800,34,DVB-S,QPSK
+115=11534,V,2300,34,DVB-S,QPSK
+116=11536,H,2960,34,DVB-S,QPSK
+117=11538,V,2900,34,DVB-S,QPSK
+118=11541,H,2600,34,S2,8PSK
+119=11542,V,2816,78,DVB-S,QPSK
+120=11551,V,1993,34,DVB-S,QPSK
+121=11552,H,4800,34,S2,8PSK
+122=11554,V,3700,56,DVB-S,QPSK
+123=11557,H,3333,56,S2,8PSK
+124=11561,V,6666,34,S2,8PSK
+125=11561,H,3333,56,DVB-S,QPSK
+126=11567,H,6666,78,DVB-S,QPSK
+127=11584,H,9875,34,S2,8PSK
+128=11590,H,2160,34,S2,8PSK
+129=11595,V,30000,23,S2,8PSK
+130=11615,H,2500,34,DVB-S,QPSK
+131=11619,H,2900,34,DVB-S,QPSK
+132=11624,V,2900,34,DVB-S,QPSK
+133=11624,H,2500,34,DVB-S,QPSK
+134=11627,H,2963,34,DVB-S,QPSK
+135=11638,H,5300,56,DVB-S,QPSK
+136=11645,H,4800,23,S2,QPSK
+137=11651,H,2590,34,DVB-S,QPSK
+138=11659,H,1500,56,S2,QPSK
+139=11663,H,5540,34,DVB-S,QPSK
+140=11664,V,6666,78,DVB-S,QPSK
+141=11669,V,3000,56,DVB-S,QPSK
+142=11671,H,7200,34,S2,8PSK
+143=11676,H,11153,78,DVB-S,QPSK
+144=11680,V,2220,34,DVB-S,QPSK
+145=11681,H,3200,56,S2,8PSK
+146=11684,V,2300,34,DVB-S,QPSK
+147=11688,H,9874,34,DVB-S,QPSK
+148=11693,V,2210,78,DVB-S,QPSK
+149=11696,H,2980,34,DVB-S,QPSK
+150=11697,V,2300,34,DVB-S,QPSK
+151=12504,H,2880,56,DVB-S,QPSK
+152=12508,H,2880,56,DVB-S,QPSK
+153=12513,H,3214,34,DVB-S,QPSK
+154=12520,H,1100,56,S2,8PSK
+155=12526,V,3600,34,S2,8PSK
+156=12527,H,2143,34,DVB-S,QPSK
+157=12535,V,2220,Auto,DVB-S,QPSK
+158=12545,H,3400,34,DVB-S,QPSK
+159=12551,V,5632,34,DVB-S,QPSK
+160=12553,H,2900,34,DVB-S,QPSK
+161=12556,V,2900,78,DVB-S,QPSK
+162=12563,V,5632,34,DVB-S,QPSK
+163=12571,V,2220,78,DVB-S,QPSK
+164=12576,V,3300,34,DVB-S,QPSK
+165=12593,V,4800,34,S2,8PSK
+166=12594,H,3300,Auto,DVB-S,QPSK
+167=12602,V,3333,78,DVB-S,QPSK
+168=12610,V,1852,34,DVB-S,QPSK
+169=12611,H,2960,34,DVB-S,QPSK
+170=12615,H,3214,34,S2,8PSK
+171=12620,H,3750,56,S2,8PSK
+172=12637,V,18400,23,S2,8PSK
+173=12648,H,2300,56,DVB-S,QPSK
+174=12652,H,4936,34,S2,8PSK
+175=12654,V,2300,78,DVB-S,QPSK
+176=12658,H,3214,34,S2,8PSK
+177=12674,V,2962,56,DVB-S,QPSK
+178=12674,H,3750,34,S2,8PSK
+179=12679,V,2894,34,DVB-S,QPSK
+180=12680,H,3750,34,S2,8PSK
+181=12684,H,3200,34,DVB-S,QPSK
+182=12688,H,3200,34,DVB-S,QPSK
+183=12692,V,3146,34,DVB-S,QPSK
+184=12694,H,6666,78,DVB-S,QPSK
+185=12696,V,5632,34,DVB-S,QPSK
+186=12701,V,2962,34,DVB-S,QPSK
+187=12705,V,2922,34,DVB-S,QPSK
+188=12706,H,3750,34,DVB-S,QPSK
+189=12710,H,3750,34,S2,8PSK
+190=12714,V,9874,34,S2,8PSK
+191=12715,H,3200,34,DVB-S,QPSK
+192=12729,V,4167,56,DVB-S,QPSK
+193=12729,H,3325,34,DVB-S,QPSK
+194=12733,H,3200,34,DVB-S,QPSK
+195=12736,V,4600,56,S2,8PSK
+196=12741,V,4167,56,DVB-S,QPSK
+197=12742,H,3500,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini
new file mode 100644
index 000000000..265104298
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0130.ini
@@ -0,0 +1,106 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0130
+2=Eutelsat Hot Bird 13B/13C/13D (13.0E)
+
+[DVB]
+0=97
+1=10719,V,27500,56,DVB-S,QPSK
+2=10758,V,27500,34,S2,8PSK
+3=10775,H,29900,56,DVB-S,QPSK
+4=10796,V,27500,56,DVB-S,QPSK
+5=10815,H,27500,56,DVB-S,QPSK
+6=10834,V,27500,34,S2,8PSK
+7=10853,H,29900,23,S2,8PSK
+8=10873,V,27500,34,DVB-S,QPSK
+9=10892,H,27500,34,DVB-S,QPSK
+10=10911,V,27500,34,S2,8PSK
+11=10930,H,30000,23,S2,8PSK
+12=10949,V,27500,34,DVB-S,QPSK
+13=10971,H,29700,23,S2,8PSK
+14=10992,V,27500,23,DVB-S,QPSK
+15=11034,V,27500,34,DVB-S,QPSK
+16=11054,H,27500,56,DVB-S,QPSK
+17=11075,V,27500,34,DVB-S,QPSK
+18=11096,H,29900,23,S2,8PSK
+19=11117,V,27500,34,DVB-S,QPSK
+20=11137,H,27500,34,DVB-S,QPSK
+21=11158,V,27500,56,DVB-S,QPSK
+22=11179,H,27500,34,DVB-S,QPSK
+23=11200,V,27500,56,DVB-S,QPSK
+24=11219,H,29900,56,DVB-S,QPSK
+25=11240,V,27500,34,DVB-S,QPSK
+26=11258,H,27500,34,S2,8PSK
+27=11278,V,27500,34,S2,8PSK
+28=11296,H,27500,34,S2,8PSK
+29=11317,V,27500,34,DVB-S,QPSK
+30=11334,H,27500,34,DVB-S,QPSK
+31=11355,V,29900,56,DVB-S,QPSK
+32=11393,V,27500,56,DVB-S,QPSK
+33=11411,H,27500,56,S2,8PSK
+34=11449,H,27500,34,S2,8PSK
+35=11471,V,27500,56,DVB-S,QPSK
+36=11488,H,27500,56,DVB-S,QPSK
+37=11508,V,27500,34,S2,8PSK
+38=11526,H,27500,34,DVB-S,QPSK
+39=11541,V,22000,56,DVB-S,QPSK
+40=11566,H,27500,34,DVB-S,QPSK
+41=11585,V,27500,34,DVB-S,QPSK
+42=11604,H,27500,56,DVB-S,QPSK
+43=11623,V,27500,34,DVB-S,QPSK
+44=11642,H,27500,34,DVB-S,QPSK
+45=11662,V,27500,34,S2,8PSK
+46=11681,H,27500,34,S2,8PSK
+47=11727,V,27500,34,DVB-S,QPSK
+48=11747,H,27500,34,DVB-S,QPSK
+49=11766,V,27500,23,DVB-S,QPSK
+50=11785,H,29900,34,S2,8PSK
+51=11804,V,27500,23,DVB-S,QPSK
+52=11823,H,27500,34,DVB-S,QPSK
+53=11843,V,29900,34,S2,8PSK
+54=11862,H,29900,56,DVB-S,QPSK
+55=11881,V,27500,34,DVB-S,QPSK
+56=11900,H,29900,34,S2,8PSK
+57=11919,V,29900,56,DVB-S,8PSK
+58=11938,H,27500,34,S2,8PSK
+59=11958,V,27500,34,DVB-S,QPSK
+60=11977,H,29900,56,DVB-S,QPSK
+61=11996,V,29900,34,S2,8PSK
+62=12015,H,27500,34,DVB-S,QPSK
+63=12034,V,29900,56,DVB-S,QPSK
+64=12054,H,29900,56,DVB-S,QPSK
+65=12073,V,29900,56,DVB-S,QPSK
+66=12092,H,29900,34,S2,8PSK
+67=12111,V,27500,34,DVB-S,QPSK
+68=12130,H,27500,34,S2,8PSK
+69=12149,V,27500,34,DVB-S,QPSK
+70=12169,H,27500,34,S2,8PSK
+71=12188,V,27500,56,DVB-S,QPSK
+72=12207,H,29900,34,S2,8PSK
+73=12226,V,27500,34,DVB-S,QPSK
+74=12265,V,27500,34,S2,8PSK
+75=12284,H,27500,56,DVB-S,QPSK
+76=12303,V,27500,34,S2,8PSK
+77=12322,H,27500,34,DVB-S,QPSK
+78=12341,V,29900,34,S2,8PSK
+79=12360,H,29900,34,S2,8PSK
+80=12380,V,27500,34,DVB-S,QPSK
+81=12399,H,27500,34,DVB-S,QPSK
+82=12418,V,29900,34,S2,8PSK
+83=12437,H,29900,34,S2,QPSK
+84=12466,V,29900,56,DVB-S,QPSK
+85=12476,H,29900,34,S2,8PSK
+86=12520,V,27500,34,DVB-S,QPSK
+87=12539,H,27500,23,S2,QPSK
+88=12558,V,27500,34,DVB-S,QPSK
+89=12577,H,27500,34,S2,8PSK
+90=12597,V,27500,34,DVB-S,QPSK
+91=12616,H,29900,56,DVB-S,QPSK
+92=12635,V,29900,56,DVB-S,QPSK
+93=12654,H,27500,56,DVB-S,QPSK
+94=12673,V,29900,56,DVB-S,QPSK
+95=12692,H,27500,34,S2,8PSK
+96=12713,V,29900,56,DVB-S,QPSK
+97=12731,H,29900,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini
new file mode 100644
index 000000000..9a9503eb5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0160.ini
@@ -0,0 +1,156 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0160
+2=Eutelsat 16A (16.0E)
+
+[DVB]
+0=147
+1=10721,H,27500,34,DVB-S,QPSK
+2=10762,H,30000,35,S2,8PSK
+3=10804,H,30000,23,S2,8PSK
+4=10845,H,30000,Auto,S2,QPSK
+5=10887,H,30000,Auto,S2,QPSK
+6=10928,H,30000,89,S2,QPSK
+7=10957,H,3750,34,S2,8PSK
+8=10961,H,3750,34,S2,8PSK
+9=10966,H,3750,34,S2,8PSK
+10=10971,H,3750,34,S2,8PSK
+11=10972,V,27500,56,DVB-S,QPSK
+12=10975,H,3750,34,S2,8PSK
+13=10977,H,24113,Auto,S2,8PSK
+14=10981,H,3462,56,S2,8PSK
+15=10992,H,2500,56,S2,8PSK
+16=10997,H,2500,56,S2,8PSK
+17=11001,H,2500,56,S2,8PSK
+18=11007,H,5000,34,S2,8PSK
+19=11011,V,27500,56,DVB-S,QPSK
+20=11012,H,3333,78,DVB-S,QPSK
+21=11016,H,1500,23,S2,8PSK
+22=11019,H,1795,Auto,S2,QPSK
+23=11023,H,7500,34,S2,8PSK
+24=11024,H,3330,Auto,DVB-S,8PSK
+25=11029,H,2300,Auto,DVB-S,QPSK
+26=11046,H,10555,34,DVB-S,QPSK
+27=11060,H,4615,56,DVB-S,QPSK
+28=11063,H,3328,34,DVB-S,QPSK
+29=11074,H,1250,34,DVB-S,QPSK
+30=11082,H,10000,Auto,S2,QPSK
+31=11092,H,3600,34,S2,8PSK
+32=11104,H,7400,34,S2,8PSK
+33=11127,H,10000,56,S2,8PSK
+34=11131,V,16593,23,S2,8PSK
+35=11139,H,10000,56,S2,8PSK
+36=11151,V,13268,23,S2,8PSK
+37=11152,H,10000,56,S2,8PSK
+38=11164,H,10000,56,S2,8PSK
+39=11175,H,10000,56,S2,8PSK
+40=11178,V,27500,34,DVB-S,QPSK
+41=11187,H,10000,56,S2,8PSK
+42=11221,H,30000,34,DVB-S,QPSK
+43=11231,V,30000,34,DVB-S,QPSK
+44=11262,H,30000,23,DVB-S,QPSK
+45=11283,V,30000,23,S2,8PSK
+46=11294,H,45000,34,S2,8PSK
+47=11303,H,30000,23,S2,8PSK
+48=11324,V,30000,34,DVB-S,QPSK
+49=11345,H,30000,35,S2,8PSK
+50=11356,H,45000,34,S2,8PSK
+51=11366,V,30000,34,DVB-S,QPSK
+52=11387,H,30000,34,DVB-S,QPSK
+53=11400,V,13846,34,S2,8PSK
+54=11427,V,27500,34,S2,8PSK
+55=11470,V,30000,56,S2,8PSK
+56=11471,H,30000,89,S2,QPSK
+57=11512,H,30000,89,S2,QPSK
+58=11512,V,29950,23,S2,8PSK
+59=11554,H,30000,56,S2,QPSK
+60=11554,V,30000,56,S2,8PSK
+61=11595,H,30000,34,S2,8PSK
+62=11595,V,30000,56,S2,8PSK
+63=11596,H,30000,89,S2,QPSK
+64=11604,V,14400,34,S2,8PSK
+65=11637,H,30000,89,S2,QPSK
+66=11645,V,27700,56,S2,QPSK
+67=11675,V,9874,34,S2,8PSK
+68=11678,H,30000,35,S2,8PSK
+69=11687,V,9874,34,S2,8PSK
+70=12508,H,3600,34,S2,8PSK
+71=12512,H,3166,23,S2,8PSK
+72=12516,H,3166,23,S2,8PSK
+73=12517,V,8000,56,S2,8PSK
+74=12521,H,30000,23,S2,8PSK
+75=12522,H,3166,23,S2,8PSK
+76=12527,H,2816,34,DVB-S,QPSK
+77=12528,V,10000,56,S2,8PSK
+78=12533,H,6333,23,S2,8PSK
+79=12538,H,3166,23,S2,8PSK
+80=12541,V,10000,56,S2,8PSK
+81=12542,H,2816,34,DVB-S,QPSK
+82=12548,H,6333,23,S2,8PSK
+83=12554,H,2816,34,DVB-S,QPSK
+84=12557,H,3166,23,S2,8PSK
+85=12559,V,2222,34,S2,QPSK
+86=12562,H,3166,23,S2,8PSK
+87=12564,H,30000,23,S2,8PSK
+88=12564,V,3617,34,DVB-S,QPSK
+89=12570,H,3703,78,DVB-S,QPSK
+90=12575,V,6000,34,S2,8PSK
+91=12593,H,7120,34,S2,8PSK
+92=12593,V,2500,23,DVB-S,QPSK
+93=12597,V,2848,23,DVB-S,QPSK
+94=12600,H,3200,23,S2,8PSK
+95=12604,H,30000,23,S2,8PSK
+96=12605,H,3166,23,S2,8PSK
+97=12605,V,7125,34,S2,QPSK
+98=12609,H,3200,23,S2,8PSK
+99=12611,V,1415,34,DVB-S,QPSK
+100=12614,H,3200,23,S2,8PSK
+101=12618,H,3166,23,S2,8PSK
+102=12620,V,3750,56,S2,8PSK
+103=12623,H,4936,34,S2,8PSK
+104=12624,V,1650,56,S2,8PSK
+105=12626,V,1650,56,S2,8PSK
+106=12628,V,1650,56,S2,8PSK
+107=12633,V,4883,12,DVB-S,QPSK
+108=12644,V,13200,34,S2,QPSK
+109=12654,H,11111,23,DVB-S,QPSK
+110=12656,V,4883,12,DVB-S,QPSK
+111=12676,H,4248,34,DVB-S,QPSK
+112=12677,V,2400,34,S2,8PSK
+113=12680,V,2400,34,S2,8PSK
+114=12683,V,2400,34,S2,8PSK
+115=12686,V,2400,34,S2,8PSK
+116=12689,V,2400,34,S2,8PSK
+117=12692,V,2400,34,S2,8PSK
+118=12695,V,2400,34,S2,8PSK
+119=12698,V,2400,34,S2,8PSK
+120=12699,H,9880,12,DVB-S,QPSK
+121=12701,V,2400,34,S2,8PSK
+122=12704,V,2400,34,S2,8PSK
+123=12707,V,2400,34,S2,8PSK
+124=12710,H,5165,35,S2,8PSK
+125=12710,V,2400,34,S2,8PSK
+126=12713,V,2400,34,S2,8PSK
+127=12717,H,4936,34,S2,8PSK
+128=12717,V,2400,34,S2,8PSK
+129=12720,V,2400,34,S2,8PSK
+130=12723,V,2400,34,S2,8PSK
+131=12723,H,4936,34,S2,8PSK
+132=12728,V,2400,34,S2,8PSK
+133=12737,V,2400,34,S2,8PSK
+134=12738,H,4500,34,DVB-S,QPSK
+135=21537,H,1070,34,S2,8PSK
+136=21538,H,1054,34,S2,8PSK
+137=21540,H,1071,34,S2,8PSK
+138=21541,H,1071,34,S2,8PSK
+139=21545,H,2143,56,S2,8PSK
+140=21550,H,1054,34,S2,8PSK
+141=21551,H,1060,23,DVB-S,QPSK
+142=21559,H,1071,34,S2,8PSK
+143=21560,H,1010,23,S2,8PSK
+144=21562,H,1010,23,S2,8PSK
+145=21563,H,1250,23,S2,8PSK
+146=21569,H,1071,34,S2,8PSK
+147=21571,H,2900,56,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini
new file mode 100644
index 000000000..52ba9e5f7
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0170.ini
@@ -0,0 +1,60 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0170
+2=Amos 5 (17.0E)
+
+[DVB]
+0=51
+1=3538,V,4444,34,DVB-S,QPSK
+2=3547,V,7200,34,S2,8PSK
+3=3553,V,1285,56,S2,8PSK
+4=3617,V,1167,23,S2,8PSK
+5=3620,V,1000,34,S2,8PSK
+6=3622,V,1000,23,S2,8PSK
+7=3626,V,2000,34,DVB-S,QPSK
+8=3626,H,1200,23,DVB-S,QPSK
+9=3665,H,3300,78,DVB-S,QPSK
+10=3685,V,1924,78,DVB-S,QPSK
+11=3688,V,2000,34,DVB-S,QPSK
+12=3728,H,3300,78,DVB-S,QPSK
+13=3731,H,2500,56,S2,8PSK
+14=3757,V,3300,78,DVB-S,QPSK
+15=3785,V,1168,34,DVB-S,QPSK
+16=3802,V,1666,34,S2,8PSK
+17=3828,V,1250,23,S2,8PSK
+18=3830,V,1480,56,S2,QPSK
+19=3852,V,1000,56,S2,QPSK
+20=4066,V,1000,23,S2,8PSK
+21=4119,V,7200,34,DVB-S,QPSK
+22=4125,V,2170,34,DVB-S,QPSK
+23=4130,V,6850,35,S2,8PSK
+24=4136,V,2500,23,S2,8PSK
+25=4139,V,1000,34,S2,8PSK
+26=4141,V,1550,34,S2,8PSK
+27=4142,V,1000,23,S2,8PSK
+28=4144,V,1334,56,DVB-S,QPSK
+29=4160,V,4166,56,DVB-S,QPSK
+30=10961,V,2200,12,S2,QPSK
+31=10983,V,3333,56,DVB-S,QPSK
+32=11038,V,1760,34,S2,QPSK
+33=11041,V,1594,34,S2,QPSK
+34=11057,V,4273,12,S2,QPSK
+35=11062,V,1250,34,S2,QPSK
+36=11064,V,1244,34,S2,QPSK
+37=11087,V,1245,34,S2,QPSK
+38=11092,V,1244,34,DVB-S,QPSK
+39=11139,V,30000,Auto,S2,QPSK
+40=11761,V,15000,34,S2,QPSK
+41=11801,V,30000,23,S2,QPSK
+42=11884,V,27500,34,DVB-S,QPSK
+43=11967,V,30000,34,S2,QPSK
+44=12004,V,30000,34,S2,QPSK
+45=12035,H,4000,Auto,S2,8PSK
+46=12068,V,45000,56,S2,QPSK
+47=12208,H,17666,45,S2,QPSK
+48=12260,V,17666,45,S2,QPSK
+49=12335,V,27500,34,DVB-S,QPSK
+50=12384,V,30000,34,S2,QPSK
+51=12418,V,30000,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini
new file mode 100644
index 000000000..fbe65c9b5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0192.ini
@@ -0,0 +1,127 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0192
+2=Astra 1KR/1L/1M/1N (19.2E)
+
+[DVB]
+0=118
+1=10729,V,22000,23,S2,8PSK
+2=10744,H,22000,56,DVB-S,QPSK
+3=10758,V,22000,56,DVB-S,QPSK
+4=10773,H,22000,34,S2,8PSK
+5=10788,V,22000,56,DVB-S,QPSK
+6=10803,H,22000,34,S2,8PSK
+7=10818,V,22000,23,S2,8PSK
+8=10832,H,22000,23,S2,8PSK
+9=10847,V,22000,56,DVB-S,QPSK
+10=10862,H,22000,23,S2,8PSK
+11=10876,V,22000,56,DVB-S,QPSK
+12=10891,H,22000,23,S2,8PSK
+13=10906,V,22000,23,S2,8PSK
+14=10921,H,22000,78,DVB-S,QPSK
+15=10936,V,22000,23,S2,8PSK
+16=10964,H,22000,23,S2,8PSK
+17=10979,V,22000,56,DVB-S,QPSK
+18=10994,H,22000,910,S2,QPSK
+19=11023,H,23500,34,S2,8PSK
+20=11038,V,22000,56,DVB-S,QPSK
+21=11053,H,22000,23,S2,8PSK
+22=11068,V,22000,56,DVB-S,QPSK
+23=11082,H,22000,34,S2,8PSK
+24=11097,V,22000,56,DVB-S,QPSK
+25=11112,H,22000,23,S2,8PSK
+26=11127,V,22000,23,S2,8PSK
+27=11156,V,22000,56,DVB-S,QPSK
+28=11171,H,22000,34,S2,8PSK
+29=11186,V,22000,56,DVB-S,QPSK
+30=11229,V,22000,23,S2,8PSK
+31=11244,H,22000,56,DVB-S,QPSK
+32=11259,V,22000,23,S2,8PSK
+33=11273,H,22000,23,S2,8PSK
+34=11288,V,22000,23,S2,8PSK
+35=11303,H,22000,23,S2,8PSK
+36=11318,V,22000,56,DVB-S,QPSK
+37=11332,H,22000,34,S2,8PSK
+38=11347,V,22000,23,S2,8PSK
+39=11362,H,22000,23,S2,8PSK
+40=11377,V,22000,23,S2,8PSK
+41=11391,H,22000,56,DVB-S,QPSK
+42=11421,H,22000,56,DVB-S,QPSK
+43=11436,V,22000,23,S2,8PSK
+44=11464,H,22000,23,S2,8PSK
+45=11494,H,22000,23,S2,8PSK
+46=11509,V,22000,56,DVB-S,QPSK
+47=11523,H,22000,56,DVB-S,QPSK
+48=11538,V,22000,56,DVB-S,QPSK
+49=11553,H,22000,34,S2,8PSK
+50=11568,V,22000,23,S2,8PSK
+51=11582,H,22000,23,S2,8PSK
+52=11597,V,22000,56,DVB-S,QPSK
+53=11612,H,22000,56,DVB-S,QPSK
+54=11627,V,22000,56,DVB-S,QPSK
+55=11641,H,22000,56,DVB-S,QPSK
+56=11671,H,22000,23,S2,8PSK
+57=11686,V,22000,56,DVB-S,QPSK
+58=11720,H,27500,34,DVB-S,QPSK
+59=11739,V,27500,34,DVB-S,QPSK
+60=11758,H,27500,34,DVB-S,QPSK
+61=11778,V,27500,34,DVB-S,QPSK
+62=11798,H,27500,34,DVB-S,QPSK
+63=11817,V,29700,56,S2,QPSK
+64=11836,H,27500,34,DVB-S,QPSK
+65=11856,V,27500,34,DVB-S,QPSK
+66=11876,H,27500,34,S2,8PSK
+67=11914,H,27500,910,S2,QPSK
+68=11934,V,27500,34,DVB-S,QPSK
+69=11954,H,27500,34,DVB-S,QPSK
+70=11973,V,27500,34,DVB-S,QPSK
+71=11992,H,27500,910,S2,QPSK
+72=12012,V,29700,56,S2,QPSK
+73=12032,H,27500,34,DVB-S,QPSK
+74=12051,V,27500,34,DVB-S,QPSK
+75=12070,H,27500,34,DVB-S,QPSK
+76=12090,V,29700,56,S2,QPSK
+77=12110,H,27500,34,DVB-S,QPSK
+78=12129,V,29700,56,S2,QPSK
+79=12148,H,27500,34,DVB-S,QPSK
+80=12168,V,29700,56,S2,QPSK
+81=12188,H,27500,34,DVB-S,QPSK
+82=12207,V,29700,56,S2,QPSK
+83=12226,H,27500,34,DVB-S,QPSK
+84=12246,V,29700,56,S2,QPSK
+85=12266,H,27500,34,DVB-S,QPSK
+86=12285,V,29700,23,S2,8PSK
+87=12304,H,27500,910,S2,QPSK
+88=12324,V,29700,56,S2,QPSK
+89=12363,V,27500,34,DVB-S,QPSK
+90=12382,H,27500,910,S2,QPSK
+91=12402,V,27500,34,DVB-S,QPSK
+92=12422,H,27500,34,DVB-S,QPSK
+93=12441,V,29700,56,S2,QPSK
+94=12460,H,27500,34,DVB-S,QPSK
+95=12480,V,27500,34,DVB-S,QPSK
+96=12515,H,22000,56,DVB-S,QPSK
+97=12522,V,22000,23,S2,8PSK
+98=12545,H,22000,56,DVB-S,QPSK
+99=12552,V,22000,56,DVB-S,QPSK
+100=12574,H,22000,23,S2,8PSK
+101=12581,V,22000,23,S2,8PSK
+102=12604,H,22000,56,DVB-S,QPSK
+103=12610,V,22000,23,S2,8PSK
+104=12633,H,22000,56,DVB-S,QPSK
+105=12640,V,22000,23,S2,8PSK
+106=12663,H,22000,56,DVB-S,QPSK
+107=12670,V,22000,23,S2,8PSK
+108=12692,H,22000,56,DVB-S,QPSK
+109=12699,V,22000,56,DVB-S,QPSK
+110=12722,H,23500,23,S2,8PSK
+111=12728,V,22000,56,DVB-S,QPSK
+112=18366,V,15000,12,S2,QPSK
+113=18515,V,3630,23,S2,8PSK
+114=18538,V,3344,34,S2,8PSK
+115=18556,V,3630,23,S2,8PSK
+116=18754,H,4500,34,DVB-S,QPSK
+117=18760,H,5500,23,S2,8PSK
+118=18766,H,3110,12,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini
new file mode 100644
index 000000000..6eb757f16
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0200.ini
@@ -0,0 +1,19 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0200
+2=Arabsat 5C (20.0E)
+
+[DVB]
+0=10
+1=3710,V,2600,34,DVB-S,QPSK
+2=3714,V,2600,34,DVB-S,QPSK
+3=3720,V,6660,34,DVB-S,QPSK
+4=3796,H,1850,34,DVB-S,QPSK
+5=3884,V,27500,56,DVB-S,QPSK
+6=3934,H,27500,78,DVB-S,QPSK
+7=4004,V,27500,34,DVB-S,QPSK
+8=4054,H,27500,34,DVB-S,QPSK
+9=4110,V,3889,78,DVB-S,QPSK
+10=4114,V,2988,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini
new file mode 100644
index 000000000..30f3d5c6e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0215.ini
@@ -0,0 +1,103 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0215
+2=Eutelsat 21B (21.5E)
+
+[DVB]
+0=94
+1=10955,H,3220,56,DVB-S,QPSK
+2=10958,H,2590,34,DVB-S,QPSK
+3=10966,H,2590,34,DVB-S,QPSK
+4=10970,H,2500,34,DVB-S,QPSK
+5=10975,H,2200,56,S2,8PSK
+6=10978,V,2170,34,DVB-S,QPSK
+7=10986,H,2150,34,DVB-S,QPSK
+8=10992,H,3220,56,S2,8PSK
+9=10995,H,2667,34,DVB-S,QPSK
+10=10998,V,8888,34,DVB-S,QPSK
+11=10999,H,3590,34,S2,8PSK
+12=11003,H,2222,34,DVB-S,QPSK
+13=11006,H,2592,56,DVB-S,QPSK
+14=11009,H,2170,78,DVB-S,QPSK
+15=11010,V,10000,34,S2,8PSK
+16=11012,H,2667,34,DVB-S,QPSK
+17=11015,H,2667,34,DVB-S,QPSK
+18=11027,H,2200,34,S2,QPSK
+19=11036,H,2100,34,DVB-S,QPSK
+20=11038,V,2000,34,DVB-S,QPSK
+21=11040,H,3600,34,DVB-S,QPSK
+22=11061,V,2000,34,DVB-S,QPSK
+23=11082,V,7400,23,S2,8PSK
+24=11093,V,10000,34,S2,8PSK
+25=11110,H,2667,34,DVB-S,QPSK
+26=11128,H,10450,45,S2,QPSK
+27=11190,V,6666,23,DVB-S,QPSK
+28=11341,H,26460,23,S2,8PSK
+29=11464,H,2590,34,DVB-S,QPSK
+30=11468,H,1317,56,S2,8PSK
+31=11470,H,2000,34,DVB-S,QPSK
+32=11473,H,1900,56,S2,8PSK
+33=11475,V,2100,34,DVB-S,QPSK
+34=11476,H,2857,34,DVB-S,QPSK
+35=11479,H,3184,34,DVB-S,QPSK
+36=11480,V,2970,34,DVB-S,QPSK
+37=11482,H,2856,34,DVB-S,QPSK
+38=11483,V,3000,34,DVB-S,QPSK
+39=11487,H,2700,56,DVB-S,QPSK
+40=11488,V,2150,34,DVB-S,QPSK
+41=11490,V,2220,34,DVB-S,QPSK
+42=11497,V,2170,34,DVB-S,QPSK
+43=11503,V,3300,34,DVB-S,QPSK
+44=11508,V,3300,34,DVB-S,QPSK
+45=11517,H,3333,56,S2,8PSK
+46=11519,V,1500,56,S2,8PSK
+47=11521,H,3300,34,DVB-S,QPSK
+48=11526,H,2200,56,DVB-S,QPSK
+49=11530,H,2200,34,DVB-S,QPSK
+50=11532,V,2857,34,DVB-S,QPSK
+51=11537,V,2755,34,DVB-S,QPSK
+52=11541,V,6534,45,S2,QPSK
+53=11546,V,2592,34,DVB-S,QPSK
+54=11550,V,2142,34,DVB-S,QPSK
+55=11557,H,3000,23,S2,8PSK
+56=11558,V,1650,34,S2,8PSK
+57=11564,V,7214,34,S2,8PSK
+58=11574,V,2300,56,S2,8PSK
+59=11578,V,3300,34,DVB-S,QPSK
+60=11581,H,5000,34,DVB-S,QPSK
+61=11582,V,2850,78,DVB-S,QPSK
+62=11585,V,1600,34,DVB-S,QPSK
+63=11588,H,5000,34,DVB-S,QPSK
+64=11590,V,2856,78,DVB-S,QPSK
+65=11593,V,1500,34,S2,8PSK
+66=11596,H,5000,34,DVB-S,QPSK
+67=11610,H,6200,78,DVB-S,QPSK
+68=11619,V,12500,23,DVB-S,QPSK
+69=11627,H,4260,56,S2,8PSK
+70=11633,H,4260,56,S2,8PSK
+71=11639,H,4260,56,S2,8PSK
+72=11645,V,1600,45,S2,8PSK
+73=11649,V,1600,34,S2,8PSK
+74=11653,V,1600,34,S2,8PSK
+75=11659,V,2850,78,DVB-S,QPSK
+76=11663,H,3220,56,S2,8PSK
+77=11665,V,2850,34,S2,8PSK
+78=11673,V,2000,34,DVB-S,QPSK
+79=11676,H,2150,34,DVB-S,QPSK
+80=11678,V,2850,78,DVB-S,QPSK
+81=11681,H,2963,34,DVB-S,QPSK
+82=11684,V,2100,34,S2,8PSK
+83=11686,H,1800,34,DVB-S,QPSK
+84=11689,H,1500,34,DVB-S,QPSK
+85=11691,V,1447,34,DVB-S,QPSK
+86=11693,H,1500,34,S2,8PSK
+87=11697,H,2500,34,DVB-S,QPSK
+88=12508,H,3300,34,DVB-S,QPSK
+89=12516,H,2200,34,DVB-S,QPSK
+90=12521,H,2857,34,DVB-S,QPSK
+91=12532,H,2220,34,DVB-S,QPSK
+92=12536,H,2200,34,DVB-S,QPSK
+93=12591,V,3124,34,DVB-S,QPSK
+94=12622,V,3124,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini
new file mode 100644
index 000000000..b1abb39c6
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0235.ini
@@ -0,0 +1,127 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0235
+2=Astra 3B (23.5E)
+
+[DVB]
+0=118
+1=11459,V,6666,78,DVB-S,QPSK
+2=11460,H,7200,34,S2,QPSK
+3=11469,H,3214,34,S2,8PSK
+4=11470,V,7500,34,S2,8PSK
+5=11476,V,3703,34,DVB-S,QPSK
+6=11479,H,4444,34,DVB-S,QPSK
+7=11484,V,4444,34,DVB-S,QPSK
+8=11490,V,3250,34,DVB-S,QPSK
+9=11490,H,3300,56,S2,8PSK
+10=11496,V,2170,Auto,DVB-S,QPSK
+11=11501,H,7200,56,S2,8PSK
+12=11501,V,3750,89,S2,8PSK
+13=11506,H,4800,34,S2,8PSK
+14=11508,V,3600,34,S2,QPSK
+15=11512,V,4800,34,S2,QPSK
+16=11516,H,4444,34,DVB-S,QPSK
+17=11516,V,3600,34,S2,QPSK
+18=11521,H,3630,23,S2,8PSK
+19=11527,H,7200,34,S2,QPSK
+20=11530,V,4800,34,S2,8PSK
+21=11532,H,3333,34,DVB-S,QPSK
+22=11579,H,4333,78,DVB-S,QPSK
+23=11583,V,10000,56,S2,8PSK
+24=11591,H,7500,34,S2,8PSK
+25=11597,V,4500,78,DVB-S,QPSK
+26=11599,H,4800,56,S2,8PSK
+27=11608,H,7200,34,S2,8PSK
+28=11619,V,3750,23,S2,8PSK
+29=11620,H,7200,34,S2,8PSK
+30=11622,V,2333,56,S2,QPSK
+31=11625,V,2333,56,S2,QPSK
+32=11628,V,2333,56,S2,QPSK
+33=11630,H,6666,78,DVB-S,QPSK
+34=11631,V,2333,56,S2,QPSK
+35=11634,V,2333,56,S2,QPSK
+36=11636,H,3630,23,S2,8PSK
+37=11642,V,2333,910,S2,8PSK
+38=11648,H,6666,78,DVB-S,QPSK
+39=11650,V,4610,34,S2,8PSK
+40=11658,V,2333,56,S2,QPSK
+41=11663,V,4666,56,S2,QPSK
+42=11668,V,3656,34,S2,8PSK
+43=11671,H,4444,34,DVB-S,QPSK
+44=11672,V,3656,34,S2,8PSK
+45=11676,V,1410,45,S2,QPSK
+46=11678,V,1024,23,S2,8PSK
+47=11679,H,6111,34,S2,8PSK
+48=11679,V,1024,23,S2,8PSK
+49=11680,V,1024,23,S2,8PSK
+50=11683,V,2734,56,DVB-S,QPSK
+51=11686,V,2750,34,S2,8PSK
+52=11720,H,28200,56,S2,8PSK
+53=11739,V,27500,23,S2,8PSK
+54=11758,H,30000,Auto,S2,QPSK
+55=11778,V,27500,910,S2,QPSK
+56=11798,H,29500,34,S2,8PSK
+57=11836,H,27500,56,DVB-S,QPSK
+58=11856,V,27500,23,S2,8PSK
+59=11876,H,29900,34,S2,8PSK
+60=11895,V,27500,56,DVB-S,QPSK
+61=11914,H,29900,23,S2,8PSK
+62=11934,V,27500,34,S2,8PSK
+63=11973,V,27500,56,DVB-S,QPSK
+64=12032,H,27500,910,S2,QPSK
+65=12070,H,27500,34,DVB-S,QPSK
+66=12110,H,27500,34,S2,8PSK
+67=12129,V,27500,23,S2,8PSK
+68=12148,H,27500,56,S2,8PSK
+69=12168,V,27500,34,DVB-S,QPSK
+70=12188,H,27500,23,S2,8PSK
+71=12207,V,27500,56,S2,8PSK
+72=12304,H,27500,56,S2,8PSK
+73=12344,H,27500,56,S2,8PSK
+74=12363,V,29500,34,S2,8PSK
+75=12382,H,30000,89,S2,8PSK
+76=12402,V,30000,34,S2,8PSK
+77=12525,H,27500,56,S2,8PSK
+78=12525,V,27500,34,DVB-S,QPSK
+79=12550,V,1663,56,S2,8PSK
+80=12550,H,14400,34,S2,8PSK
+81=12554,V,1666,56,S2,8PSK
+82=12562,V,4937,34,S2,8PSK
+83=12568,V,4937,34,S2,8PSK
+84=12572,V,3300,78,DVB-S,QPSK
+85=12576,V,3300,78,DVB-S,QPSK
+86=12580,V,4937,34,S2,8PSK
+87=12591,H,7200,34,S2,8PSK
+88=12593,V,9600,34,S2,8PSK
+89=12601,H,6666,78,DVB-S,QPSK
+90=12608,V,4800,34,S2,8PSK
+91=12609,H,6666,78,DVB-S,QPSK
+92=12614,V,5000,56,S2,8PSK
+93=12621,H,4936,34,S2,8PSK
+94=12621,V,3750,34,S2,8PSK
+95=12631,H,7200,34,S2,8PSK
+96=12636,V,5000,34,S2,8PSK
+97=12652,V,3333,34,S2,8PSK
+98=12656,V,3600,34,S2,8PSK
+99=12658,H,7200,34,S2,8PSK
+100=12661,V,3600,34,S2,8PSK
+101=12671,H,6666,78,DVB-S,QPSK
+102=12674,V,3600,34,S2,8PSK
+103=12677,V,2200,34,S2,8PSK
+104=12680,V,2400,56,S2,8PSK
+105=12680,H,6666,78,DVB-S,QPSK
+106=12683,V,2400,56,S2,8PSK
+107=12687,V,2400,56,S2,8PSK
+108=12690,H,7200,34,S2,8PSK
+109=12692,V,4800,34,S2,8PSK
+110=12697,V,4800,34,S2,8PSK
+111=12699,H,6666,78,S2,8PSK
+112=12710,V,4800,34,S2,8PSK
+113=12717,V,4800,34,S2,QPSK
+114=12723,V,4800,34,S2,QPSK
+115=12725,H,30000,89,S2,8PSK
+116=12730,V,3600,34,S2,QPSK
+117=12735,V,3600,34,S2,QPSK
+118=12740,V,2400,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini
new file mode 100644
index 000000000..f72c91b41
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0255.ini
@@ -0,0 +1,19 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0255
+2=Eutelsat 25B/Es'hail 1 (25.5E)
+
+[DVB]
+0=10
+1=11046,H,27500,34,DVB-S,QPSK
+2=11142,V,27500,34,DVB-S,QPSK
+3=11547,V,27500,23,S2,8PSK
+4=11566,H,27500,34,DVB-S,8PSK
+5=11585,V,27500,23,S2,8PSK
+6=11604,H,27500,34,DVB-S,QPSK
+7=11623,V,27500,23,S2,8PSK
+8=11642,H,27500,23,S2,8PSK
+9=11678,H,27500,56,DVB-S,QPSK
+10=21421,V,27500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini
new file mode 100644
index 000000000..299779fb5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0260.ini
@@ -0,0 +1,107 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0260
+2=Badr 4/5/6 (26.0E)
+
+[DVB]
+0=98
+1=3958,V,12000,34,DVB-S,QPSK
+2=10730,H,27500,34,DVB-S,QPSK
+3=10730,V,27500,34,S2,8PSK
+4=10770,H,27500,34,DVB-S,QPSK
+5=10810,H,27500,34,DVB-S,QPSK
+6=10810,V,27500,12,S2,8PSK
+7=10850,H,27500,56,DVB-S,QPSK
+8=10850,V,27500,34,DVB-S,QPSK
+9=10890,H,27500,34,S2,8PSK
+10=10890,V,27500,34,S2,8PSK
+11=10930,H,27500,34,DVB-S,QPSK
+12=10930,V,27500,34,S2,8PSK
+13=11228,V,27500,34,DVB-S,QPSK
+14=11557,H,2960,34,DVB-S,QPSK
+15=11563,H,1500,34,DVB-S,QPSK
+16=11727,H,27500,Auto,S2,8PSK
+17=11747,V,27500,34,DVB-S,QPSK
+18=11785,V,27500,34,DVB-S,QPSK
+19=11804,H,27500,34,DVB-S,QPSK
+20=11823,V,27500,12,S2,8PSK
+21=11843,H,27500,34,DVB-S,QPSK
+22=11862,V,27500,34,DVB-S,QPSK
+23=11881,H,27500,56,S2,8PSK
+24=11900,V,27500,34,DVB-S,QPSK
+25=11919,H,27500,34,DVB-S,QPSK
+26=11938,V,27500,34,DVB-S,QPSK
+27=11958,H,27500,34,DVB-S,QPSK
+28=11996,H,27500,34,DVB-S,QPSK
+29=12015,V,27500,34,DVB-S,QPSK
+30=12034,H,27500,34,DVB-S,QPSK
+31=12054,V,27500,34,DVB-S,QPSK
+32=12073,H,27500,34,DVB-S,QPSK
+33=12092,V,27500,34,DVB-S,QPSK
+34=12111,H,27500,34,DVB-S,QPSK
+35=12130,V,27500,34,DVB-S,QPSK
+36=12149,H,30000,56,S2,QPSK
+37=12169,V,22000,34,S2,QPSK
+38=12182,H,16200,34,DVB-S,QPSK
+39=12207,V,27500,34,DVB-S,QPSK
+40=12226,H,27500,34,DVB-S,QPSK
+41=12245,V,27500,56,S2,QPSK
+42=12265,H,27500,56,S2,QPSK
+43=12284,V,27500,34,DVB-S,QPSK
+44=12303,H,27500,34,DVB-S,QPSK
+45=12322,V,27500,34,DVB-S,QPSK
+46=12360,V,27500,34,DVB-S,QPSK
+47=12399,V,27500,34,S2,8PSK
+48=12418,H,27500,34,S2,8PSK
+49=12437,V,27500,34,DVB-S,QPSK
+50=12456,H,27500,34,DVB-S,QPSK
+51=12476,V,27500,34,DVB-S,QPSK
+52=12523,H,27500,34,DVB-S,QPSK
+53=12547,H,2000,34,DVB-S,QPSK
+54=12550,H,2950,34,DVB-S,QPSK
+55=12550,V,7000,56,S2,8PSK
+56=12558,V,7000,56,S2,8PSK
+57=12559,H,2220,34,DVB-S,QPSK
+58=12562,H,2220,34,DVB-S,QPSK
+59=12565,H,2220,34,DVB-S,QPSK
+60=12567,V,2200,34,DVB-S,QPSK
+61=12568,H,1850,34,DVB-S,QPSK
+62=12570,V,2200,34,DVB-S,QPSK
+63=12570,H,1820,34,DVB-S,QPSK
+64=12575,H,2200,56,DVB-S,QPSK
+65=12576,V,7000,56,S2,8PSK
+66=12579,H,2100,34,DVB-S,QPSK
+67=12586,V,2220,34,DVB-S,QPSK
+68=12587,H,2000,34,DVB-S,QPSK
+69=12591,H,2200,34,DVB-S,QPSK
+70=12591,V,2200,34,DVB-S,QPSK
+71=12594,H,2200,34,DVB-S,QPSK
+72=12600,V,7000,56,S2,QPSK
+73=12602,H,2960,56,DVB-S,QPSK
+74=12605,V,2220,34,DVB-S,QPSK
+75=12607,H,3000,34,DVB-S,QPSK
+76=12608,V,1820,34,DVB-S,QPSK
+77=12611,V,2220,34,DVB-S,QPSK
+78=12618,H,2220,34,DVB-S,QPSK
+79=12620,V,2200,34,DVB-S,QPSK
+80=12644,V,1850,34,DVB-S,QPSK
+81=12647,H,2950,34,DVB-S,QPSK
+82=12647,V,1595,34,S2,8PSK
+83=12656,H,2892,34,DVB-S,QPSK
+84=12666,H,2400,34,DVB-S,QPSK
+85=12672,H,4440,34,DVB-S,QPSK
+86=12679,H,2220,78,DVB-S,QPSK
+87=12683,V,27500,34,DVB-S,QPSK
+88=12705,H,2220,56,DVB-S,QPSK
+89=12708,H,2220,56,DVB-S,QPSK
+90=12711,H,2220,34,DVB-S,8PSK
+91=12711,V,5632,34,DVB-S,QPSK
+92=12717,V,2143,56,DVB-S,QPSK
+93=12718,H,3000,56,DVB-S,QPSK
+94=12722,H,3000,56,DVB-S,QPSK
+95=12729,H,2200,34,DVB-S,QPSK
+96=12734,H,3000,34,DVB-S,QPSK
+97=12736,V,5632,34,DVB-S,QPSK
+98=12740,H,2200,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini
new file mode 100644
index 000000000..07c5ccebe
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0282.ini
@@ -0,0 +1,101 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0282
+2=Astra 2E/2F/2G (28.2E)
+
+[DVB]
+0=92
+1=10714,H,22000,56,DVB-S,QPSK
+2=10729,V,22000,56,DVB-S,QPSK
+3=10744,H,22000,56,DVB-S,QPSK
+4=10758,V,22000,56,DVB-S,QPSK
+5=10773,H,22000,56,DVB-S,QPSK
+6=10788,V,22000,56,DVB-S,QPSK
+7=10803,H,22000,56,DVB-S,QPSK
+8=10818,V,22000,56,DVB-S,QPSK
+9=10832,H,22000,56,DVB-S,QPSK
+10=10847,V,23000,23,S2,8PSK
+11=10862,H,23000,23,S2,8PSK
+12=10876,V,22000,56,DVB-S,QPSK
+13=10891,H,22000,56,DVB-S,QPSK
+14=10906,V,22000,56,DVB-S,QPSK
+15=10936,V,23000,23,S2,8PSK
+16=10964,H,22000,56,DVB-S,QPSK
+17=10994,H,22000,56,DVB-S,QPSK
+18=11023,H,23000,23,S2,8PSK
+19=11053,H,23000,34,S2,8PSK
+20=11068,V,23000,23,S2,8PSK
+21=11082,H,22000,56,DVB-S,QPSK
+22=11097,V,23000,23,S2,8PSK
+23=11112,H,22000,56,DVB-S,QPSK
+24=11126,V,22000,56,DVB-S,QPSK
+25=11141,H,22000,56,DVB-S,QPSK
+26=11171,H,22000,56,DVB-S,QPSK
+27=11224,H,27500,23,DVB-S,QPSK
+28=11224,V,27500,23,DVB-S,QPSK
+29=11264,V,27500,23,DVB-S,QPSK
+30=11264,H,27500,23,DVB-S,QPSK
+31=11306,V,27500,23,DVB-S,QPSK
+32=11306,H,27500,23,DVB-S,QPSK
+33=11344,V,27500,23,DVB-S,QPSK
+34=11344,H,27500,23,DVB-S,QPSK
+35=11386,V,27500,23,DVB-S,QPSK
+36=11386,H,27500,23,DVB-S,QPSK
+37=11426,H,27500,23,DVB-S,QPSK
+38=11426,V,27500,23,DVB-S,QPSK
+39=11464,H,22000,56,DVB-S,QPSK
+40=11479,V,22000,56,DVB-S,QPSK
+41=11509,V,22000,56,DVB-S,QPSK
+42=11523,H,22000,56,DVB-S,QPSK
+43=11538,V,23000,23,S2,8PSK
+44=11553,H,22000,56,DVB-S,QPSK
+45=11568,V,22000,56,DVB-S,QPSK
+46=11582,H,22000,56,DVB-S,QPSK
+47=11597,V,22000,56,DVB-S,QPSK
+48=11618,V,1562,56,S2,QPSK
+49=11671,H,22000,56,DVB-S,QPSK
+50=11675,H,30000,56,S2,QPSK
+51=11686,V,22000,56,DVB-S,QPSK
+52=11720,H,29500,34,S2,QPSK
+53=11739,V,29500,34,S2,QPSK
+54=11758,H,29500,34,S2,QPSK
+55=11798,H,29500,34,S2,QPSK
+56=11817,V,27500,23,DVB-S,QPSK
+57=11836,H,27500,56,DVB-S,QPSK
+58=11856,V,29500,34,S2,QPSK
+59=11876,H,27500,23,DVB-S,QPSK
+60=11895,V,27500,23,DVB-S,QPSK
+61=11914,H,27500,56,DVB-S,QPSK
+62=11934,V,27500,56,DVB-S,QPSK
+63=11954,H,27500,23,DVB-S,QPSK
+64=11973,V,29500,34,S2,QPSK
+65=11992,H,27500,23,DVB-S,QPSK
+66=12012,V,29500,34,S2,QPSK
+67=12051,V,27500,23,DVB-S,QPSK
+68=12070,H,27500,56,DVB-S,QPSK
+69=12090,V,29500,34,S2,QPSK
+70=12110,H,27500,56,DVB-S,QPSK
+71=12148,H,27500,56,DVB-S,QPSK
+72=12168,V,29500,34,S2,QPSK
+73=12188,H,27500,56,DVB-S,QPSK
+74=12207,V,27500,56,DVB-S,QPSK
+75=12226,H,29500,34,S2,QPSK
+76=12246,V,29500,34,S2,QPSK
+77=12266,H,27500,56,DVB-S,QPSK
+78=12285,V,27500,23,DVB-S,QPSK
+79=12324,V,29500,34,S2,QPSK
+80=12344,H,29500,34,S2,QPSK
+81=12363,V,29500,34,S2,QPSK
+82=12441,V,29500,34,S2,QPSK
+83=12460,H,29500,34,S2,QPSK
+84=12480,V,27500,23,DVB-S,QPSK
+85=12522,V,27000,Auto,DVB-S,QPSK
+86=12573,H,6960,23,S2,QPSK
+87=12581,V,7200,34,S2,8PSK
+88=12582,H,6960,23,S2,QPSK
+89=12603,V,3095,Auto,S2,QPSK
+90=12683,H,6960,23,S2,8PSK
+91=12692,H,6960,23,S2,8PSK
+92=12699,H,4640,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini
new file mode 100644
index 000000000..196196c95
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0305.ini
@@ -0,0 +1,96 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0305
+2=Arabsat 5A (30.5E)
+
+[DVB]
+0=87
+1=3770,V,2200,34,DVB-S,QPSK
+2=3820,V,2848,34,DVB-S,QPSK
+3=3880,V,3888,78,DVB-S,QPSK
+4=3884,V,3888,78,DVB-S,QPSK
+5=3888,V,3888,78,DVB-S,QPSK
+6=3947,V,2200,34,DVB-S,QPSK
+7=3951,V,2220,34,DVB-S,QPSK
+8=4061,V,1615,78,DVB-S,QPSK
+9=4126,V,2892,34,DVB-S,QPSK
+10=10717,H,2069,23,S2,8PSK
+11=10721,H,4300,23,S2,8PSK
+12=10727,H,4300,23,DVB-S,QPSK
+13=10744,H,4300,23,DVB-S,QPSK
+14=10749,H,3125,Auto,DVB-S,QPSK
+15=10757,H,2220,34,DVB-S,QPSK
+16=10760,H,2050,23,S2,8PSK
+17=10765,H,1950,34,S2,QPSK
+18=10770,H,1650,23,S2,8PSK
+19=10777,H,2960,34,DVB-S,QPSK
+20=10782,H,2960,34,DVB-S,QPSK
+21=10797,H,8000,56,S2,8PSK
+22=10805,H,3885,56,DVB-S,QPSK
+23=10816,H,8000,56,DVB-S,QPSK
+24=10827,H,5800,34,DVB-S,QPSK
+25=10832,V,2780,56,DVB-S,QPSK
+26=10858,V,2960,34,DVB-S,QPSK
+27=10924,H,17000,34,DVB-S,QPSK
+28=10940,H,8000,56,DVB-S,QPSK
+29=10946,H,2400,78,DVB-S,QPSK
+30=12503,V,2220,34,DVB-S,QPSK
+31=12506,V,2220,34,DVB-S,QPSK
+32=12507,H,2220,34,DVB-S,QPSK
+33=12509,V,2222,34,DVB-S,QPSK
+34=12511,V,2200,34,DVB-S,QPSK
+35=12514,V,2220,34,DVB-S,QPSK
+36=12516,H,2230,34,DVB-S,QPSK
+37=12523,V,6000,Auto,DVB-S,QPSK
+38=12533,V,3890,34,DVB-S,QPSK
+39=12538,V,2690,34,DVB-S,QPSK
+40=12539,H,2960,34,DVB-S,QPSK
+41=12543,V,2410,34,S2,8PSK
+42=12559,H,2963,34,DVB-S,QPSK
+43=12568,H,2960,Auto,DVB-S,QPSK
+44=12576,H,1613,Auto,S2,QPSK
+45=12588,H,3000,34,DVB-S,QPSK
+46=12593,H,2960,34,DVB-S,QPSK
+47=12596,H,2220,34,DVB-S,QPSK
+48=12596,V,1800,78,DVB-S,QPSK
+49=12603,V,3300,34,DVB-S,QPSK
+50=12607,V,2590,56,DVB-S,QPSK
+51=12608,H,2200,34,DVB-S,QPSK
+52=12610,V,2970,34,DVB-S,QPSK
+53=12611,H,3000,34,DVB-S,QPSK
+54=12614,H,2200,34,DVB-S,QPSK
+55=12614,V,3820,89,S2,QPSK
+56=12618,H,2960,34,DVB-S,QPSK
+57=12621,V,3800,34,S2,8PSK
+58=12624,V,2220,34,DVB-S,QPSK
+59=12630,V,2893,34,DVB-S,QPSK
+60=12634,V,2893,34,DVB-S,QPSK
+61=12638,V,2894,34,DVB-S,QPSK
+62=12641,V,2894,34,DVB-S,QPSK
+63=12644,V,2894,34,DVB-S,QPSK
+64=12647,H,2960,34,DVB-S,QPSK
+65=12648,V,2894,34,DVB-S,QPSK
+66=12651,H,3885,34,DVB-S,QPSK
+67=12652,V,2893,34,DVB-S,QPSK
+68=12655,H,2410,34,DVB-S,QPSK
+69=12656,V,1660,56,S2,8PSK
+70=12667,H,4112,34,DVB-S,QPSK
+71=12667,V,2220,34,DVB-S,QPSK
+72=12671,V,2600,34,DVB-S,QPSK
+73=12675,V,4300,34,DVB-S,QPSK
+74=12679,V,3000,34,DVB-S,QPSK
+75=12685,V,4300,34,DVB-S,QPSK
+76=12697,V,4300,34,DVB-S,QPSK
+77=12708,V,2590,34,DVB-S,QPSK
+78=12712,H,2220,34,DVB-S,QPSK
+79=12713,V,1850,34,DVB-S,QPSK
+80=12716,V,2600,34,DVB-S,QPSK
+81=12719,H,2960,34,DVB-S,QPSK
+82=12719,V,3000,34,DVB-S,QPSK
+83=12722,H,2200,34,DVB-S,QPSK
+84=12724,V,2220,34,DVB-S,QPSK
+85=12732,V,2000,78,DVB-S,QPSK
+86=12733,H,2960,34,DVB-S,QPSK
+87=12737,H,2220,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini
new file mode 100644
index 000000000..fe4f41569
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0308.ini
@@ -0,0 +1,30 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0308
+2=Eutelsat 31A (30.8E)
+
+[DVB]
+0=21
+1=10960,H,3330,78,DVB-S,QPSK
+2=10965,H,3330,78,DVB-S,QPSK
+3=10970,H,3330,78,DVB-S,QPSK
+4=10975,H,3330,78,DVB-S,QPSK
+5=10979,H,3330,78,DVB-S,QPSK
+6=10984,H,3330,56,DVB-S,QPSK
+7=10988,H,3330,78,DVB-S,QPSK
+8=10992,H,3330,78,DVB-S,QPSK
+9=11004,H,7500,34,S2,8PSK
+10=11011,H,3330,56,DVB-S,QPSK
+11=11015,H,3330,78,DVB-S,QPSK
+12=11019,H,3330,78,DVB-S,QPSK
+13=11024,H,3330,78,DVB-S,QPSK
+14=11044,H,21000,56,S2,QPSK
+15=11560,H,21000,56,S2,8PSK
+16=11622,H,2300,56,DVB-S,QPSK
+17=11624,H,2200,56,DVB-S,QPSK
+18=11627,H,2300,56,DVB-S,QPSK
+19=11630,H,2222,56,DVB-S,QPSK
+20=11644,H,2300,910,S2,8PSK
+21=11651,H,7500,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini
new file mode 100644
index 000000000..be556fdd2
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0310.ini
@@ -0,0 +1,10 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0310
+2=Hylas 2 (31.0E)
+
+[DVB]
+0=1
+1=20036,H,10000,12,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini
new file mode 100644
index 000000000..6581c9169
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0315.ini
@@ -0,0 +1,24 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0315
+2=Astra 5B (31.5E)
+
+[DVB]
+0=15
+1=11758,H,27500,34,DVB-S,QPSK
+2=11817,V,27500,34,DVB-S,QPSK
+3=11934,V,30000,23,S2,8PSK
+4=11954,H,27500,56,S2,8PSK
+5=11973,V,27500,56,S2,8PSK
+6=12012,V,30000,34,S2,8PSK
+7=12070,H,30000,34,S2,8PSK
+8=12090,V,30000,34,S2,8PSK
+9=12168,V,30000,34,S2,8PSK
+10=12207,V,27500,56,S2,8PSK
+11=12246,V,30000,34,S2,8PSK
+12=12266,H,27500,56,S2,8PSK
+13=12324,V,30000,34,S2,8PSK
+14=12402,V,30000,34,S2,8PSK
+15=12480,V,30000,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini
new file mode 100644
index 000000000..b395913cc
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0330.ini
@@ -0,0 +1,47 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0330
+2=Eutelsat 33B/33C/Intelsat 28 (33.0E)
+
+[DVB]
+0=38
+1=10968,V,6665,45,S2,QPSK
+2=10975,H,30000,910,S2,QPSK
+3=10976,V,6665,45,S2,QPSK
+4=11043,H,7200,34,S2,8PSK
+5=11052,H,7200,56,S2,8PSK
+6=11072,H,3333,78,DVB-S,QPSK
+7=11077,H,3750,34,S2,8PSK
+8=11094,H,3000,34,S2,8PSK
+9=11098,H,2960,56,DVB-S,QPSK
+10=11101,H,2222,56,DVB-S,QPSK
+11=11105,H,3333,34,S2,8PSK
+12=11154,V,15710,12,DVB-S,QPSK
+13=11429,V,10098,35,S2,QPSK
+14=11457,V,1704,56,S2,8PSK
+15=11461,V,2000,78,DVB-S,QPSK
+16=11467,V,3600,34,S2,8PSK
+17=11471,V,3820,34,S2,8PSK
+18=11475,V,3820,34,S2,8PSK
+19=11476,H,3820,34,S2,8PSK
+20=11580,H,2478,23,S2,8PSK
+21=11583,H,2478,23,S2,8PSK
+22=11593,H,15710,12,DVB-S,QPSK
+23=11605,V,3333,56,S2,8PSK
+24=11608,H,3810,56,S2,8PSK
+25=12630,V,2400,35,S2,8PSK
+26=12634,V,4800,34,S2,8PSK
+27=12640,V,2400,23,S2,8PSK
+28=12643,V,2400,23,S2,8PSK
+29=12646,V,4800,34,S2,8PSK
+30=12650,V,2400,23,S2,8PSK
+31=12653,V,2400,23,S2,8PSK
+32=12656,V,2400,23,S2,8PSK
+33=12684,V,2050,56,S2,8PSK
+34=12691,V,2222,78,DVB-S,QPSK
+35=12698,V,3333,34,DVB-S,QPSK
+36=12722,V,16730,34,S2,QPSK
+37=12736,V,4444,34,DVB-S,QPSK
+38=12742,V,4444,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini
new file mode 100644
index 000000000..49042dfb7
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0360.ini
@@ -0,0 +1,111 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0360
+2=Eutelsat 36A/36B (36.0E)
+
+[DVB]
+0=102
+1=11053,V,2894,34,DVB-S,QPSK
+2=11057,V,2894,34,DVB-S,QPSK
+3=11212,H,14400,35,S2,8PSK
+4=11221,V,30000,56,S2,QPSK
+5=11263,V,30000,56,S2,QPSK
+6=11304,V,30000,56,S2,QPSK
+7=11346,V,30000,56,S2,QPSK
+8=11387,V,30000,56,S2,QPSK
+9=11429,V,30000,56,S2,QPSK
+10=11429,H,2893,34,DVB-S,QPSK
+11=11442,H,2500,56,S2,8PSK
+12=11474,V,30000,56,DVB-S,QPSK
+13=11481,V,2200,34,S2,8PSK
+14=11510,V,30000,56,DVB-S,QPSK
+15=11590,V,2524,35,S2,QPSK
+16=11593,V,2524,35,S2,QPSK
+17=11727,H,27500,34,S2,8PSK
+18=11727,V,27500,34,DVB-S,QPSK
+19=11747,H,27500,34,DVB-S,QPSK
+20=11747,V,27500,34,S2,8PSK
+21=11766,V,27500,34,DVB-S,QPSK
+22=11766,H,27500,34,S2,8PSK
+23=11785,H,27500,34,DVB-S,QPSK
+24=11785,V,27500,34,DVB-S,QPSK
+25=11804,V,27500,34,S2,8PSK
+26=11804,H,27500,34,S2,8PSK
+27=11823,H,27500,34,DVB-S,QPSK
+28=11823,V,27500,34,S2,8PSK
+29=11843,V,27500,34,DVB-S,QPSK
+30=11843,H,27500,34,S2,8PSK
+31=11862,H,27500,34,DVB-S,QPSK
+32=11862,V,27500,34,DVB-S,QPSK
+33=11881,V,27500,34,DVB-S,QPSK
+34=11881,H,27500,34,DVB-S,QPSK
+35=11900,H,26480,12,DVB-S,QPSK
+36=11900,V,27500,34,DVB-S,QPSK
+37=11919,V,27500,34,S2,8PSK
+38=11919,H,27500,34,S2,8PSK
+39=11938,V,27500,34,S2,8PSK
+40=11940,H,27500,34,DVB-S,QPSK
+41=11958,V,27500,34,DVB-S,QPSK
+42=11958,H,27500,34,S2,8PSK
+43=11977,H,27500,34,DVB-S,QPSK
+44=11977,V,27500,34,DVB-S,QPSK
+45=11996,V,27500,34,S2,8PSK
+46=11996,H,27500,34,S2,8PSK
+47=12015,H,27500,34,DVB-S,QPSK
+48=12015,V,27500,34,S2,8PSK
+49=12034,V,27500,34,DVB-S,QPSK
+50=12034,H,27500,34,S2,8PSK
+51=12054,H,27500,34,DVB-S,QPSK
+52=12054,V,27500,34,S2,8PSK
+53=12073,H,27500,34,S2,8PSK
+54=12073,V,27500,34,DVB-S,QPSK
+55=12092,H,27500,23,S2,8PSK
+56=12092,V,27500,34,DVB-S,QPSK
+57=12111,H,27500,34,S2,8PSK
+58=12130,V,27500,34,S2,8PSK
+59=12149,H,27500,34,S2,8PSK
+60=12169,V,27500,34,S2,8PSK
+61=12174,H,4340,34,DVB-S,QPSK
+62=12190,H,20000,34,DVB-S,QPSK
+63=12207,V,27500,34,S2,8PSK
+64=12226,H,27500,34,DVB-S,QPSK
+65=12245,V,27500,34,DVB-S,QPSK
+66=12245,H,27500,34,DVB-S,QPSK
+67=12265,H,27500,34,DVB-S,QPSK
+68=12284,V,27500,34,DVB-S,QPSK
+69=12303,H,27500,34,DVB-S,QPSK
+70=12322,V,27500,34,DVB-S,QPSK
+71=12322,H,23437,34,DVB-S,QPSK
+72=12341,H,27500,34,DVB-S,QPSK
+73=12360,V,27500,34,S2,8PSK
+74=12360,H,26480,12,DVB-S,QPSK
+75=12380,H,27500,34,DVB-S,QPSK
+76=12399,V,27500,34,DVB-S,QPSK
+77=12418,H,27500,34,S2,8PSK
+78=12437,V,27500,34,S2,8PSK
+79=12440,H,23437,23,DVB-S,QPSK
+80=12456,H,27500,34,DVB-S,QPSK
+81=12476,V,27500,34,DVB-S,QPSK
+82=12476,H,26040,23,DVB-S,QPSK
+83=12511,H,4340,12,DVB-S,QPSK
+84=12520,H,4340,12,DVB-S,QPSK
+85=12522,V,1346,34,DVB-S,QPSK
+86=12540,V,2220,34,DVB-S,QPSK
+87=12557,V,1346,34,S2,QPSK
+88=12563,H,7120,34,DVB-S,QPSK
+89=12571,H,2894,34,DVB-S,QPSK
+90=12572,V,1786,34,S2,8PSK
+91=12575,H,2894,34,DVB-S,QPSK
+92=12608,V,6200,34,S2,QPSK
+93=12629,H,3444,34,S2,8PSK
+94=12654,V,1800,78,DVB-S,QPSK
+95=12689,V,2170,34,DVB-S,QPSK
+96=12693,V,2532,34,DVB-S,QPSK
+97=12699,V,6000,34,DVB-S,QPSK
+98=12703,V,2200,78,DVB-S,QPSK
+99=12706,V,1800,78,DVB-S,QPSK
+100=12709,V,2200,78,DVB-S,QPSK
+101=12713,V,1800,78,DVB-S,QPSK
+102=12716,V,1800,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini
new file mode 100644
index 000000000..25b53cd3d
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0380.ini
@@ -0,0 +1,79 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0380
+2=Paksat 1R (38.0E)
+
+[DVB]
+0=70
+1=3715,V,7200,34,DVB-S,QPSK
+2=3732,V,18000,89,S2,QPSK
+3=3762,V,4340,34,DVB-S,QPSK
+4=3770,V,7700,78,DVB-S,QPSK
+5=3775,V,1004,34,DVB-S,QPSK
+6=3782,V,2170,34,DVB-S,QPSK
+7=3800,V,7300,34,DVB-S,QPSK
+8=3806,V,1444,34,S2,QPSK
+9=3818,V,2200,34,DVB-S,QPSK
+10=3824,V,2800,34,DVB-S,QPSK
+11=3830,H,2000,34,DVB-S,QPSK
+12=3833,V,2600,34,DVB-S,QPSK
+13=3856,V,2894,34,DVB-S,QPSK
+14=3860,V,3333,34,DVB-S,QPSK
+15=3865,V,2894,34,DVB-S,QPSK
+16=3959,V,7234,34,DVB-S,QPSK
+17=3966,V,2800,34,DVB-S,QPSK
+18=3973,V,6510,34,DVB-S,QPSK
+19=3976,H,1750,34,DVB-S,QPSK
+20=3979,V,3255,34,DVB-S,QPSK
+21=3981,H,2222,34,DVB-S,QPSK
+22=3984,V,2893,34,DVB-S,QPSK
+23=3992,V,2170,56,DVB-S,QPSK
+24=4003,V,15550,34,DVB-S,QPSK
+25=4005,H,13845,78,DVB-S,QPSK
+26=4013,V,2893,34,DVB-S,QPSK
+27=4023,V,5700,35,S2,8PSK
+28=4031,V,1078,34,DVB-S,QPSK
+29=4037,V,4800,56,S2,QPSK
+30=4042,V,2800,34,S2,QPSK
+31=4047,V,3255,34,DVB-S,QPSK
+32=4054,V,7000,34,DVB-S,QPSK
+33=4060,H,23000,56,DVB-S,QPSK
+34=4060,V,2893,34,DVB-S,QPSK
+35=4073,V,6150,34,S2,QPSK
+36=4081,V,3255,34,DVB-S,QPSK
+37=4085,V,2960,34,DVB-S,QPSK
+38=4090,V,3330,34,DVB-S,QPSK
+39=4093,V,2527,34,DVB-S,QPSK
+40=4098,H,1600,34,DVB-S,QPSK
+41=4101,V,2800,34,DVB-S,QPSK
+42=4105,V,2310,56,DVB-S,QPSK
+43=4114,V,5700,34,DVB-S,QPSK
+44=4124,V,5000,34,DVB-S,QPSK
+45=4130,V,2500,34,DVB-S,QPSK
+46=4133,V,2220,89,S2,QPSK
+47=4135,H,3330,34,DVB-S,QPSK
+48=4141,V,2800,34,DVB-S,QPSK
+49=4158,V,12000,34,DVB-S,QPSK
+50=4168,V,2800,34,DVB-S,QPSK
+51=4172,V,2800,34,DVB-S,QPSK
+52=4180,V,2170,34,DVB-S,QPSK
+53=4184,V,2800,34,S2,QPSK
+54=4188,V,2170,34,DVB-S,QPSK
+55=10971,V,1000,56,S2,8PSK
+56=10972,V,1000,56,S2,8PSK
+57=10990,V,1650,34,DVB-S,QPSK
+58=10992,V,1500,34,DVB-S,QPSK
+59=11103,V,3012,34,DVB-S,QPSK
+60=11122,V,1808,34,DVB-S,QPSK
+61=11124,V,1300,34,DVB-S,QPSK
+62=11150,V,3760,34,DVB-S,QPSK
+63=11167,V,3000,78,DVB-S,QPSK
+64=11184,V,2000,34,DVB-S,QPSK
+65=11188,V,2000,34,DVB-S,QPSK
+66=11191,V,2000,34,DVB-S,QPSK
+67=12652,V,2050,34,DVB-S,QPSK
+68=12687,V,2170,78,DVB-S,QPSK
+69=12691,V,3333,34,DVB-S,QPSK
+70=12696,V,3333,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini
new file mode 100644
index 000000000..e77919753
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0390.ini
@@ -0,0 +1,60 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0390
+2=Hellas Sat 2 (39.0E)
+
+[DVB]
+0=51
+1=10955,V,4444,34,S2,8PSK
+2=10960,V,1852,34,DVB-S,QPSK
+3=10968,V,4400,34,DVB-S,QPSK
+4=10972,V,3300,34,DVB-S,QPSK
+5=10977,V,3300,34,DVB-S,QPSK
+6=10981,V,3300,34,DVB-S,QPSK
+7=10987,V,3333,78,DVB-S,QPSK
+8=11012,V,30000,34,S2,8PSK
+9=11053,V,30000,34,S2,8PSK
+10=11078,V,3333,34,DVB-S,QPSK
+11=11083,V,4400,34,DVB-S,QPSK
+12=11091,V,1666,34,DVB-S,QPSK
+13=11097,H,6111,34,DVB-S,QPSK
+14=11104,V,14400,34,DVB-S,QPSK
+15=11135,V,30000,23,S2,8PSK
+16=11464,H,3224,78,DVB-S,QPSK
+17=11473,H,4444,34,S2,8PSK
+18=11479,H,3190,56,DVB-S,QPSK
+19=11482,H,2905,34,DVB-S,QPSK
+20=11486,H,2509,56,S2,8PSK
+21=11496,H,2960,34,DVB-S,QPSK
+22=11500,H,2960,23,S2,8PSK
+23=11503,H,2200,56,DVB-S,QPSK
+24=11507,H,2220,34,DVB-S,QPSK
+25=11559,H,1950,23,S2,8PSK
+26=11565,H,2250,34,DVB-S,QPSK
+27=11608,H,2100,34,DVB-S,QPSK
+28=11611,H,2100,34,DVB-S,QPSK
+29=11618,H,2500,78,DVB-S,QPSK
+30=11622,H,2800,56,DVB-S,QPSK
+31=11624,V,3255,34,DVB-S,QPSK
+32=11625,H,3333,34,DVB-S,QPSK
+33=11628,H,2800,56,DVB-S,QPSK
+34=11632,H,2800,56,DVB-S,QPSK
+35=11649,H,4433,34,DVB-S,QPSK
+36=11663,H,5925,34,DVB-S,QPSK
+37=11670,H,3720,34,DVB-S,QPSK
+38=11679,H,3700,56,DVB-S,QPSK
+39=11685,H,3700,34,DVB-S,QPSK
+40=11692,H,2300,78,DVB-S,QPSK
+41=12524,V,30000,78,DVB-S,QPSK
+42=12524,H,30000,78,DVB-S,QPSK
+43=12565,V,30000,78,DVB-S,QPSK
+44=12565,H,30000,78,DVB-S,QPSK
+45=12606,V,30000,78,DVB-S,QPSK
+46=12606,H,30000,78,DVB-S,QPSK
+47=12647,V,30000,78,DVB-S,QPSK
+48=12647,H,30000,34,S2,8PSK
+49=12688,V,30000,78,DVB-S,QPSK
+50=12688,H,30000,78,DVB-S,QPSK
+51=12729,V,30000,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini
new file mode 100644
index 000000000..c1a56c845
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0400.ini
@@ -0,0 +1,30 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0400
+2=Express AM7 (40.0E)
+
+[DVB]
+0=21
+1=3557,V,2894,78,DVB-S,QPSK
+2=3558,H,3720,34,S2,8PSK
+3=3561,V,2905,34,DVB-S,QPSK
+4=3563,H,3600,34,S2,8PSK
+5=3565,V,2896,34,DVB-S,QPSK
+6=3566,H,1850,34,S2,8PSK
+7=3569,V,2905,34,DVB-S,QPSK
+8=3573,V,2896,34,DVB-S,QPSK
+9=3577,V,2905,34,DVB-S,QPSK
+10=3581,V,2894,34,DVB-S,QPSK
+11=3585,V,2905,34,DVB-S,QPSK
+12=3589,V,2905,34,DVB-S,QPSK
+13=3592,V,2894,34,DVB-S,QPSK
+14=3615,V,14990,34,S2,8PSK
+15=3635,V,15280,34,S2,8PSK
+16=3665,H,14990,34,S2,8PSK
+17=3675,V,33483,78,DVB-S,QPSK
+18=3685,H,15284,34,S2,8PSK
+19=3725,H,28108,35,S2,QPSK
+20=3739,V,1922,78,DVB-S,QPSK
+21=3742,V,2893,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini
new file mode 100644
index 000000000..3d884a86b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0420.ini
@@ -0,0 +1,199 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0420
+2=Türksat 2A/3A/4A (42.0E)
+
+[DVB]
+0=190
+1=10962,H,16666,34,DVB-S,QPSK
+2=10970,V,30000,56,S2,8PSK
+3=10974,H,2660,56,S2,8PSK
+4=10978,H,2660,56,S2,8PSK
+5=10982,H,2660,56,S2,8PSK
+6=10986,H,2660,56,S2,8PSK
+7=10997,H,3333,56,DVB-S,QPSK
+8=11001,H,3200,34,DVB-S,QPSK
+9=11006,H,2222,56,DVB-S,QPSK
+10=11012,V,30000,56,DVB-S,QPSK
+11=11014,H,9600,34,DVB-S,QPSK
+12=11021,H,2222,34,DVB-S,QPSK
+13=11027,H,2222,56,DVB-S,QPSK
+14=11031,H,2222,56,DVB-S,QPSK
+15=11039,H,4800,23,S2,8PSK
+16=11045,H,4800,34,DVB-S,QPSK
+17=11053,H,8000,34,DVB-S,QPSK
+18=11054,V,30000,34,S2,8PSK
+19=11062,H,4820,34,DVB-S,QPSK
+20=11068,H,2400,56,DVB-S,QPSK
+21=11071,H,2200,56,DVB-S,QPSK
+22=11096,V,30000,56,DVB-S,QPSK
+23=11096,H,30000,56,DVB-S,QPSK
+24=11128,H,3150,56,S2,QPSK
+25=11137,H,2960,56,DVB-S,QPSK
+26=11138,V,13000,12,S2,QPSK
+27=11142,H,2221,56,DVB-S,QPSK
+28=11146,H,3330,Auto,DVB-S,QPSK
+29=11152,H,2222,Auto,DVB-S,QPSK
+30=11156,V,2222,56,DVB-S,QPSK
+31=11157,H,3180,56,DVB-S,QPSK
+32=11161,V,2222,56,DVB-S,QPSK
+33=11161,H,3180,56,DVB-S,QPSK
+34=11165,H,3180,56,DVB-S,QPSK
+35=11169,V,3333,56,DVB-S,QPSK
+36=11169,H,3180,56,DVB-S,QPSK
+37=11173,H,3180,56,DVB-S,QPSK
+38=11174,V,2200,Auto,DVB-S,QPSK
+39=11177,H,2222,56,DVB-S,QPSK
+40=11178,V,3600,56,DVB-S,QPSK
+41=11180,H,2960,56,S2,8PSK
+42=11183,V,2222,56,DVB-S,QPSK
+43=11187,H,2080,56,DVB-S,QPSK
+44=11191,H,2070,78,DVB-S,QPSK
+45=11195,H,4000,56,S2,8PSK
+46=11196,V,3200,56,DVB-S,QPSK
+47=11458,V,3200,34,S2,8PSK
+48=11462,V,3200,34,S2,8PSK
+49=11466,V,3200,34,S2,8PSK
+50=11470,V,3200,34,S2,8PSK
+51=11472,H,23450,56,DVB-S,QPSK
+52=11473,V,3200,34,S2,8PSK
+53=11477,V,3200,34,S2,8PSK
+54=11480,V,3200,34,S2,8PSK
+55=11486,V,3200,34,S2,8PSK
+56=11490,V,3200,56,DVB-S,QPSK
+57=11496,V,2960,56,DVB-S,QPSK
+58=11500,V,2222,56,DVB-S,QPSK
+59=11504,V,3200,56,DVB-S,QPSK
+60=11509,H,30000,23,DVB-S,QPSK
+61=11518,V,2222,Auto,DVB-S,QPSK
+62=11521,V,2222,Auto,DVB-S,QPSK
+63=11524,V,2222,Auto,DVB-S,QPSK
+64=11528,V,2960,Auto,DVB-S,QPSK
+65=11540,H,3600,56,DVB-S,QPSK
+66=11545,H,4425,56,DVB-S,QPSK
+67=11550,H,2110,56,S2,QPSK
+68=11558,V,30000,23,DVB-S,QPSK
+69=11566,H,3200,56,S2,QPSK
+70=11573,H,1800,56,DVB-S,QPSK
+71=11574,V,2222,56,DVB-S,QPSK
+72=11577,H,2222,Auto,DVB-S,QPSK
+73=11594,V,25000,23,DVB-S,QPSK
+74=11596,H,22000,34,S2,QPSK
+75=11622,V,2960,56,DVB-S,QPSK
+76=11624,V,2222,56,DVB-S,QPSK
+77=11624,H,2960,56,DVB-S,QPSK
+78=11626,V,2300,56,DVB-S,QPSK
+79=11627,H,4444,56,DVB-S,QPSK
+80=11633,V,2222,78,DVB-S,QPSK
+81=11637,V,2222,56,DVB-S,QPSK
+82=11642,V,2220,56,DVB-S,QPSK
+83=11647,H,3333,Auto,DVB-S,QPSK
+84=11649,V,2960,Auto,DVB-S,QPSK
+85=11651,H,2222,56,DVB-S,QPSK
+86=11652,V,2222,56,DVB-S,QPSK
+87=11656,V,3200,56,DVB-S,QPSK
+88=11660,H,7500,34,S2,8PSK
+89=11667,H,2960,56,DVB-S,QPSK
+90=11675,H,2222,Auto,DVB-S,QPSK
+91=11676,V,24444,34,DVB-S,QPSK
+92=11680,H,1666,23,DVB-S,QPSK
+93=11683,H,2222,56,DVB-S,QPSK
+94=11691,H,2222,56,DVB-S,QPSK
+95=11691,V,2222,56,DVB-S,QPSK
+96=11727,V,27000,56,DVB-S,QPSK
+97=11746,H,27500,56,DVB-S,QPSK
+98=11775,V,27500,34,S2,8PSK
+99=11794,H,27500,56,DVB-S,QPSK
+100=11797,V,8800,56,DVB-S,QPSK
+101=11807,V,8000,34,S2,8PSK
+102=11821,H,17000,34,DVB-S,QPSK
+103=11824,V,8000,34,DVB-S,QPSK
+104=11853,H,25000,23,S2,8PSK
+105=11855,V,30000,34,DVB-S,QPSK
+106=11880,H,20000,23,S2,8PSK
+107=11883,V,4800,56,DVB-S,QPSK
+108=11916,V,30000,34,DVB-S,QPSK
+109=11958,V,27500,56,DVB-S,QPSK
+110=11977,H,27500,56,DVB-S,QPSK
+111=11986,V,9600,56,DVB-S,QPSK
+112=11999,V,11666,23,S2,8PSK
+113=12009,V,4444,34,DVB-S,QPSK
+114=12015,H,27500,56,DVB-S,QPSK
+115=12034,V,27500,56,DVB-S,QPSK
+116=12054,H,27500,56,DVB-S,QPSK
+117=12073,V,27500,56,S2,8PSK
+118=12079,H,6400,56,DVB-S,QPSK
+119=12086,H,2960,56,DVB-S,QPSK
+120=12090,H,2960,56,DVB-S,QPSK
+121=12095,H,4800,56,DVB-S,QPSK
+122=12103,H,8333,23,S2,8PSK
+123=12123,H,15000,34,S2,8PSK
+124=12130,V,27500,56,DVB-S,QPSK
+125=12188,V,27500,56,DVB-S,QPSK
+126=12196,H,9600,23,S2,8PSK
+127=12209,H,10000,34,S2,8PSK
+128=12213,V,5833,23,S2,8PSK
+129=12219,H,6500,34,DVB-S,QPSK
+130=12220,V,4800,56,DVB-S,QPSK
+131=12228,V,8400,56,DVB-S,QPSK
+132=12238,V,7200,56,DVB-S,QPSK
+133=12245,H,27500,56,S2,8PSK
+134=12265,V,27500,56,DVB-S,QPSK
+135=12303,V,27500,56,DVB-S,QPSK
+136=12329,H,6666,23,S2,8PSK
+137=12336,H,5520,34,DVB-S,QPSK
+138=12344,V,30000,34,DVB-S,QPSK
+139=12346,H,9600,34,DVB-S,QPSK
+140=12356,H,7100,23,S2,8PSK
+141=12379,H,30000,34,DVB-S,QPSK
+142=12380,V,27500,34,DVB-S,QPSK
+143=12422,V,27500,34,DVB-S,QPSK
+144=12422,H,30000,34,DVB-S,QPSK
+145=12442,H,2963,78,DVB-S,QPSK
+146=12447,H,2400,34,DVB-S,QPSK
+147=12455,H,10800,23,S2,8PSK
+148=12458,V,30000,34,DVB-S,QPSK
+149=12509,H,3333,56,DVB-S,QPSK
+150=12513,H,2215,56,DVB-S,QPSK
+151=12516,H,2222,56,DVB-S,QPSK
+152=12519,H,2222,56,DVB-S,QPSK
+153=12524,V,22500,23,DVB-S,QPSK
+154=12540,H,30000,34,DVB-S,QPSK
+155=12559,V,27500,23,DVB-S,QPSK
+156=12562,H,2960,56,S2,8PSK
+157=12576,H,2090,78,DVB-S,QPSK
+158=12578,H,2222,56,DVB-S,QPSK
+159=12588,V,22500,34,DVB-S,QPSK
+160=12588,H,3200,56,S2,8PSK
+161=12595,H,4800,56,S2,8PSK
+162=12605,V,27500,23,DVB-S,QPSK
+163=12606,H,2222,78,DVB-S,QPSK
+164=12611,H,5924,56,DVB-S,QPSK
+165=12617,H,3333,56,DVB-S,QPSK
+166=12620,V,2244,56,DVB-S,QPSK
+167=12621,H,3333,56,DVB-S,QPSK
+168=12624,V,2170,56,DVB-S,QPSK
+169=12627,V,2278,78,DVB-S,QPSK
+170=12632,V,2220,78,DVB-S,8PSK
+171=12635,V,2240,56,S2,8PSK
+172=12639,V,5000,56,S2,8PSK
+173=12641,H,30000,23,DVB-S,QPSK
+174=12646,V,4000,56,S2,8PSK
+175=12651,V,5000,34,S2,8PSK
+176=12658,V,2222,56,DVB-S,QPSK
+177=12673,V,9600,34,DVB-S,QPSK
+178=12685,H,30000,34,DVB-S,QPSK
+179=12687,V,11400,34,DVB-S,QPSK
+180=12699,V,7700,56,S2,QPSK
+181=12711,V,2278,78,DVB-S,QPSK
+182=12714,V,2960,56,DVB-S,QPSK
+183=12718,V,2278,56,DVB-S,QPSK
+184=12721,V,2278,78,DVB-S,QPSK
+185=12723,V,2222,56,DVB-S,QPSK
+186=12728,V,2222,56,DVB-S,QPSK
+187=12729,H,27500,23,DVB-S,QPSK
+188=12731,V,2222,56,DVB-S,QPSK
+189=12746,V,2222,56,DVB-S,QPSK
+190=18669,H,22500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini
new file mode 100644
index 000000000..a7e5fdb79
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0435.ini
@@ -0,0 +1,35 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0435
+2=Astra 2G (43.5E)
+
+[DVB]
+0=26
+1=10964,H,22000,56,DVB-S,QPSK
+2=10994,H,22000,56,DVB-S,QPSK
+3=11023,H,23000,23,S2,8PSK
+4=11053,H,23000,34,S2,8PSK
+5=11068,V,23000,23,S2,8PSK
+6=11082,H,22000,56,DVB-S,QPSK
+7=11097,V,23000,23,S2,8PSK
+8=11112,H,22000,56,DVB-S,QPSK
+9=11126,V,22000,56,DVB-S,QPSK
+10=11141,H,22000,56,DVB-S,QPSK
+11=11171,H,22000,56,DVB-S,QPSK
+12=11224,V,27500,23,DVB-S,QPSK
+13=11224,H,27500,23,DVB-S,QPSK
+14=11264,V,27500,23,DVB-S,QPSK
+15=11264,H,27500,23,DVB-S,QPSK
+16=11464,H,22000,56,DVB-S,QPSK
+17=11479,V,22000,56,DVB-S,QPSK
+18=11509,V,22000,56,DVB-S,QPSK
+19=11523,H,22000,56,DVB-S,QPSK
+20=11538,V,23000,23,S2,8PSK
+21=11553,H,22000,56,DVB-S,QPSK
+22=11568,V,22000,56,DVB-S,QPSK
+23=11582,H,22000,56,DVB-S,QPSK
+24=11597,V,22000,56,DVB-S,QPSK
+25=11671,H,22000,56,DVB-S,QPSK
+26=11686,V,22000,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini
new file mode 100644
index 000000000..0737fb4f1
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0450.ini
@@ -0,0 +1,23 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0450
+2=Intelsat 12 (45.0E)
+
+[DVB]
+0=14
+1=11451,H,3254,78,DVB-S,QPSK
+2=11468,V,27689,56,DVB-S,8PSK
+3=11493,V,2960,78,DVB-S,QPSK
+4=11506,V,1808,34,DVB-S,QPSK
+5=11509,V,10000,23,S2,8PSK
+6=11517,V,2960,78,DVB-S,QPSK
+7=11523,V,5787,34,DVB-S,QPSK
+8=11550,V,28800,35,S2,8PSK
+9=11591,V,27689,56,DVB-S,8PSK
+10=11632,V,27689,56,DVB-S,8PSK
+11=11673,V,27689,56,DVB-S,8PSK
+12=12518,H,14236,34,S2,8PSK
+13=12568,V,8335,23,S2,8PSK
+14=12580,H,6600,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini
new file mode 100644
index 000000000..7611715ec
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0460.ini
@@ -0,0 +1,49 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0460
+2=AzerSpace 1/Africasat 1a (46.0E)
+
+[DVB]
+0=40
+1=3730,V,30000,34,S2,8PSK
+2=3753,V,30000,23,S2,8PSK
+3=3833,V,1077,23,S2,8PSK
+4=3953,V,1180,34,S2,8PSK
+5=4016,V,1200,34,S2,8PSK
+6=4021,V,1180,34,S2,8PSK
+7=4024,V,1190,34,S2,8PSK
+8=4026,V,1200,34,S2,8PSK
+9=4028,V,1166,34,S2,8PSK
+10=4105,H,1320,56,S2,QPSK
+11=4145,H,6666,23,DVB-S,QPSK
+12=10961,V,7500,23,S2,8PSK
+13=10968,V,5000,23,S2,8PSK
+14=10973,H,2221,56,DVB-S,QPSK
+15=10979,V,7500,56,S2,8PSK
+16=10987,V,7500,56,S2,8PSK
+17=10988,H,2400,56,S2,8PSK
+18=10991,H,1536,56,DVB-S,QPSK
+19=10999,V,3570,56,DVB-S,QPSK
+20=11002,V,2222,56,DVB-S,QPSK
+21=11005,V,2222,56,DVB-S,QPSK
+22=11008,V,2222,56,DVB-S,QPSK
+23=11011,V,2222,56,DVB-S,QPSK
+24=11014,V,2222,56,DVB-S,QPSK
+25=11015,H,30000,56,DVB-S,QPSK
+26=11024,V,12700,56,DVB-S,QPSK
+27=11038,H,3333,56,S2,8PSK
+28=11039,V,3700,78,DVB-S,QPSK
+29=11047,V,10000,34,DVB-S,QPSK
+30=11058,H,7500,56,DVB-S,QPSK
+31=11061,V,3333,34,DVB-S,QPSK
+32=11067,H,7500,56,S2,8PSK
+33=11073,H,3333,78,DVB-S,QPSK
+34=11077,V,2500,56,S2,8PSK
+35=11095,H,27500,56,DVB-S,QPSK
+36=11110,V,2222,56,DVB-S,QPSK
+37=11134,H,27500,56,DVB-S,QPSK
+38=11135,V,28800,56,S2,8PSK
+39=11175,V,28800,56,S2,8PSK
+40=11175,H,27500,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini
new file mode 100644
index 000000000..bc671123f
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0475.ini
@@ -0,0 +1,31 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0475
+2=Intelsat 10 (47.5E)
+
+[DVB]
+0=22
+1=11475,V,2700,34,DVB-S,QPSK
+2=11531,V,2755,34,DVB-S,QPSK
+3=11548,V,2000,56,S2,QPSK
+4=11606,V,2200,56,S2,8PSK
+5=11639,V,1900,78,DVB-S,QPSK
+6=11642,V,1480,34,S2,8PSK
+7=11644,V,1450,56,DVB-S,QPSK
+8=11647,V,3200,34,DVB-S,QPSK
+9=11654,V,1450,56,DVB-S,QPSK
+10=11665,V,2000,34,DVB-S,QPSK
+11=11670,V,2123,34,DVB-S,QPSK
+12=11675,V,1900,78,DVB-S,QPSK
+13=12517,H,6660,78,DVB-S,QPSK
+14=12532,V,14395,34,S2,8PSK
+15=12548,H,6111,Auto,DVB-S,QPSK
+16=12564,H,3750,56,S2,QPSK
+17=12574,H,6111,34,DVB-S,QPSK
+18=12602,V,10112,12,S2,QPSK
+19=12673,H,7200,34,DVB-S,QPSK
+20=12691,H,14400,34,S2,8PSK
+21=12712,H,13200,34,DVB-S,QPSK
+22=12721,V,10000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini
new file mode 100644
index 000000000..fa955de65
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0480.ini
@@ -0,0 +1,10 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0480
+2=Afghansat 1 (48.0E)
+
+[DVB]
+0=1
+1=11293,V,27500,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini
new file mode 100644
index 000000000..a85ad11b9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0490.ini
@@ -0,0 +1,30 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0490
+2=Yamal 202 (49.0E)
+
+[DVB]
+0=21
+1=3635,H,3230,34,DVB-S,QPSK
+2=3640,H,3215,34,DVB-S,QPSK
+3=3644,H,3230,34,DVB-S,QPSK
+4=3660,H,3333,34,DVB-S,QPSK
+5=3714,H,8888,34,DVB-S,QPSK
+6=3735,V,3219,34,DVB-S,QPSK
+7=3743,H,34075,34,DVB-S,QPSK
+8=3752,V,3230,34,DVB-S,QPSK
+9=3781,H,1900,34,DVB-S,QPSK
+10=3793,H,1800,34,DVB-S,QPSK
+11=3826,H,2960,34,DVB-S,QPSK
+12=3832,V,1500,34,DVB-S,QPSK
+13=3866,H,3310,Auto,DVB-S,QPSK
+14=3908,H,1356,12,DVB-S,QPSK
+15=3936,H,3230,34,DVB-S,QPSK
+16=3941,H,4000,34,DVB-S,QPSK
+17=3950,H,3500,34,S2,8PSK
+18=3961,H,8570,34,DVB-S,QPSK
+19=3970,H,4275,34,DVB-S,QPSK
+20=3976,H,4285,34,DVB-S,QPSK
+21=4078,H,14400,89,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini
new file mode 100644
index 000000000..5bbfe6297
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0505.ini
@@ -0,0 +1,11 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0505
+2=NSS 5 (50.5E)
+
+[DVB]
+0=2
+1=4172,V,13330,34,DVB-S,QPSK
+2=12710,V,26670,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini
new file mode 100644
index 000000000..355d0e5b5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0510.ini
@@ -0,0 +1,28 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0510
+2=Express AM6 (51.0E)
+
+[DVB]
+0=19
+1=3675,V,33483,78,DVB-S,QPSK
+2=3708,H,4280,78,DVB-S,QPSK
+3=10974,H,8150,34,DVB-S,QPSK
+4=10990,V,3111,34,DVB-S,QPSK
+5=10995,H,3255,34,DVB-S,QPSK
+6=11001,H,4160,56,S2,QPSK
+7=11044,V,44950,34,DVB-S,QPSK
+8=11471,H,2400,34,DVB-S,QPSK
+9=11474,H,4666,34,DVB-S,QPSK
+10=11504,H,2200,56,DVB-S,QPSK
+11=11506,H,1481,34,DVB-S,QPSK
+12=11520,H,4800,56,DVB-S,QPSK
+13=12511,V,2170,34,DVB-S,QPSK
+14=12528,H,2100,34,S2,8PSK
+15=12545,H,3000,23,DVB-S,QPSK
+16=12572,H,1320,78,DVB-S,QPSK
+17=12594,V,2050,34,DVB-S,QPSK
+18=12594,H,2050,34,DVB-S,QPSK
+19=12631,V,3000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini
new file mode 100644
index 000000000..8631604aa
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0520.ini
@@ -0,0 +1,11 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0520
+2=TurkmenÄlem52E/MonacoSat (52.0E)
+
+[DVB]
+0=2
+1=12265,V,27500,23,S2,QPSK
+2=12303,V,27500,23,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini
new file mode 100644
index 000000000..2eb001a81
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0525.ini
@@ -0,0 +1,24 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0525
+2=Y1A (52.5E)
+
+[DVB]
+0=15
+1=11747,H,27500,89,S2,QPSK
+2=11766,V,27500,56,DVB-S,QPSK
+3=11785,H,27500,56,DVB-S,QPSK
+4=11823,H,27500,89,S2,QPSK
+5=11862,H,27500,56,DVB-S,QPSK
+6=11881,V,27500,56,DVB-S,QPSK
+7=11900,H,27500,56,DVB-S,QPSK
+8=11938,H,27500,56,DVB-S,QPSK
+9=11958,V,27500,78,DVB-S,QPSK
+10=11977,H,27500,89,S2,QPSK
+11=11996,V,27500,56,DVB-S,QPSK
+12=12015,H,27500,56,DVB-S,QPSK
+13=12034,V,27500,23,S2,8PSK
+14=12073,V,27500,78,DVB-S,QPSK
+15=12092,H,27500,89,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini
new file mode 100644
index 000000000..965c41f15
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0530.ini
@@ -0,0 +1,28 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0530
+2=Express AM6 (53.0E)
+
+[DVB]
+0=19
+1=3675,V,33483,78,DVB-S,QPSK
+2=3708,H,4280,78,DVB-S,QPSK
+3=10974,H,8150,34,DVB-S,QPSK
+4=10990,V,3111,34,DVB-S,QPSK
+5=10995,H,3255,34,DVB-S,QPSK
+6=11001,H,4160,56,S2,QPSK
+7=11044,V,44950,34,DVB-S,QPSK
+8=11471,H,2400,34,DVB-S,QPSK
+9=11474,H,4666,34,DVB-S,QPSK
+10=11504,H,2200,56,DVB-S,QPSK
+11=11506,H,1481,34,DVB-S,QPSK
+12=11520,H,4800,56,DVB-S,QPSK
+13=12511,V,2170,34,DVB-S,QPSK
+14=12528,H,2100,34,S2,8PSK
+15=12545,H,3000,23,DVB-S,QPSK
+16=12572,H,1320,78,DVB-S,QPSK
+17=12594,H,2050,34,DVB-S,QPSK
+18=12594,V,2050,34,DVB-S,QPSK
+19=12631,V,3000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini
new file mode 100644
index 000000000..b2fdf5a5c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0549.ini
@@ -0,0 +1,37 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0549
+2=G-Sat 8/Yamal 402 (54.9E)
+
+[DVB]
+0=28
+1=10845,V,32727,Auto,S2,QPSK
+2=10962,V,5926,34,DVB-S,QPSK
+3=10968,V,2951,Auto,DVB-S,QPSK
+4=10976,H,2200,35,S2,8PSK
+5=11008,V,3600,34,S2,QPSK
+6=11045,V,40000,23,DVB-S,QPSK
+7=11156,V,22000,12,S2,QPSK
+8=11186,V,6642,34,S2,8PSK
+9=11215,H,13000,12,S2,QPSK
+10=11225,V,30000,89,S2,8PSK
+11=11232,H,17000,34,S2,QPSK
+12=11265,V,30000,34,DVB-S,QPSK
+13=11305,V,10000,34,S2,QPSK
+14=11345,V,30000,34,S2,8PSK
+15=11425,V,30000,12,S2,QPSK
+16=11486,V,8000,12,S2,QPSK
+17=11531,H,3015,34,DVB-S,QPSK
+18=11554,V,3800,56,DVB-S,QPSK
+19=11686,H,3333,23,DVB-S,QPSK
+20=12522,V,27500,34,S2,8PSK
+21=12531,H,2500,56,S2,QPSK
+22=12604,V,16080,56,DVB-S,QPSK
+23=12630,H,3333,34,DVB-S,QPSK
+24=12674,V,14940,34,S2,8PSK
+25=12685,H,30000,34,S2,QPSK
+26=12694,V,15282,34,S2,8PSK
+27=12720,H,30000,34,S2,QPSK
+28=12732,V,9557,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini
new file mode 100644
index 000000000..bed5b87b5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0560.ini
@@ -0,0 +1,31 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0560
+2=Express AT1 (56.0E)
+
+[DVB]
+0=22
+1=11727,H,27500,34,S2,8PSK
+2=11881,H,27500,34,S2,8PSK
+3=11919,H,27500,34,S2,8PSK
+4=11958,H,27500,34,S2,8PSK
+5=11996,H,27500,34,S2,8PSK
+6=12034,H,27500,34,S2,8PSK
+7=12073,H,27500,34,S2,8PSK
+8=12111,H,27500,34,S2,8PSK
+9=12130,V,27500,34,S2,8PSK
+10=12149,H,27500,34,DVB-S,QPSK
+11=12169,V,27500,56,S2,8PSK
+12=12188,H,27500,34,DVB-S,QPSK
+13=12226,H,27500,34,DVB-S,QPSK
+14=12245,V,27500,56,S2,8PSK
+15=12265,H,27500,34,S2,8PSK
+16=12284,V,27500,34,DVB-S,QPSK
+17=12303,H,27500,34,S2,8PSK
+18=12322,V,27500,56,S2,8PSK
+19=12341,H,27500,34,S2,8PSK
+20=12399,V,27500,56,S2,8PSK
+21=12437,V,27500,56,DVB-S,QPSK
+22=12476,V,27500,56,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini
new file mode 100644
index 000000000..27df36311
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0570.ini
@@ -0,0 +1,67 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0570
+2=NSS 12 (57.0E)
+
+[DVB]
+0=58
+1=3632,V,2625,23,DVB-S,QPSK
+2=3636,V,1762,23,DVB-S,QPSK
+3=3661,H,8882,34,DVB-S,QPSK
+4=3800,V,20000,35,S2,QPSK
+5=3912,V,2222,23,DVB-S,QPSK
+6=4026,H,2963,34,DVB-S,QPSK
+7=4031,H,3689,34,DVB-S,QPSK
+8=4055,V,26000,34,DVB-S,QPSK
+9=4061,H,3500,12,DVB-S,QPSK
+10=4065,H,3500,12,DVB-S,QPSK
+11=4069,V,3500,12,DVB-S,QPSK
+12=4071,H,3500,12,DVB-S,QPSK
+13=4074,V,3500,12,DVB-S,QPSK
+14=4079,H,2000,78,DVB-S,QPSK
+15=4082,H,2000,12,DVB-S,QPSK
+16=4147,V,9246,56,S2,QPSK
+17=11007,H,4883,12,DVB-S,QPSK
+18=11039,V,3100,34,DVB-S,QPSK
+19=11042,H,2600,34,DVB-S,QPSK
+20=11051,H,1230,34,DVB-S,QPSK
+21=11105,H,45000,45,S2,QPSK
+22=11129,V,2200,34,DVB-S,QPSK
+23=11134,V,2200,34,S2,QPSK
+24=11140,V,2200,56,S2,8PSK
+25=11181,V,2400,56,S2,8PSK
+26=11184,V,1211,34,S2,QPSK
+27=11186,V,2290,34,DVB-S,QPSK
+28=11189,V,1775,34,S2,QPSK
+29=11191,V,1452,34,S2,QPSK
+30=11460,H,3500,23,DVB-S,QPSK
+31=11461,H,3500,23,DVB-S,QPSK
+32=11464,H,3100,34,DVB-S,QPSK
+33=11469,H,3100,34,DVB-S,QPSK
+34=11473,H,3100,34,DVB-S,QPSK
+35=11499,H,4090,23,DVB-S,QPSK
+36=11503,H,2880,12,DVB-S,QPSK
+37=11509,H,3333,23,DVB-S,QPSK
+38=11510,H,3330,Auto,DVB-S,QPSK
+39=11520,H,2222,56,S2,8PSK
+40=11554,H,3300,34,S2,QPSK
+41=11598,H,4200,78,DVB-S,QPSK
+42=11604,H,4200,78,DVB-S,QPSK
+43=11605,H,45000,45,S2,QPSK
+44=11606,V,1852,56,S2,8PSK
+45=11645,V,3333,34,DVB-S,QPSK
+46=12292,V,2500,34,DVB-S,QPSK
+47=12306,V,2000,34,DVB-S,QPSK
+48=12313,V,2123,56,DVB-S,QPSK
+49=12316,V,2123,34,DVB-S,QPSK
+50=12413,V,1600,34,DVB-S,QPSK
+51=12429,V,3500,34,S2,8PSK
+52=12554,V,1800,34,DVB-S,QPSK
+53=12556,V,1600,34,DVB-S,QPSK
+54=12559,V,1600,34,DVB-S,QPSK
+55=12571,V,2500,34,DVB-S,QPSK
+56=12579,V,4000,34,DVB-S,QPSK
+57=12621,V,2000,34,DVB-S,QPSK
+58=12625,V,2200,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini
new file mode 100644
index 000000000..1a711cf26
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0600.ini
@@ -0,0 +1,48 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0600
+2=Intelsat 904 (60.0E)
+
+[DVB]
+0=39
+1=3676,H,3617,34,DVB-S,QPSK
+2=3698,V,1666,56,S2,QPSK
+3=3718,H,13333,78,DVB-S,QPSK
+4=3730,H,2815,34,DVB-S,QPSK
+5=3740,H,10750,56,DVB-S,QPSK
+6=3744,V,18315,56,S2,QPSK
+7=3756,V,2315,34,DVB-S,QPSK
+8=3759,V,2315,34,DVB-S,QPSK
+9=3765,V,5000,34,DVB-S,QPSK
+10=3768,V,2067,34,S2,8PSK
+11=3775,V,9361,12,S2,8PSK
+12=3964,V,5000,34,DVB-S,QPSK
+13=4168,V,14240,34,S2,8PSK
+14=4185,V,2895,34,DVB-S,QPSK
+15=4194,H,1594,Auto,DVB-S,QPSK
+16=4194,V,6111,34,DVB-S,QPSK
+17=10957,V,3700,34,DVB-S,QPSK
+18=10962,V,3730,34,DVB-S,QPSK
+19=10964,H,3327,34,DVB-S,QPSK
+20=10967,V,2573,78,DVB-S,QPSK
+21=10973,V,3330,34,DVB-S,QPSK
+22=10977,V,3225,34,DVB-S,QPSK
+23=11020,V,3700,34,DVB-S,QPSK
+24=11460,V,3730,34,DVB-S,QPSK
+25=11464,V,1000,78,DVB-S,QPSK
+26=11473,V,1324,56,S2,8PSK
+27=11475,V,1324,56,S2,8PSK
+28=11477,V,1324,56,S2,8PSK
+29=11481,V,2645,34,S2,8PSK
+30=11484,V,2645,78,DVB-S,QPSK
+31=11490,V,5788,34,DVB-S,QPSK
+32=11497,V,4284,78,DVB-S,QPSK
+33=11502,V,4284,78,DVB-S,QPSK
+34=11555,H,30000,34,S2,8PSK
+35=11567,V,10000,78,DVB-S,QPSK
+36=11595,H,29270,56,DVB-S,QPSK
+37=11622,V,8527,34,S2,8PSK
+38=11635,H,30000,34,S2,8PSK
+39=11675,H,30000,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini
new file mode 100644
index 000000000..ae5cf34bf
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0620.ini
@@ -0,0 +1,70 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0620
+2=Intelsat 902 (62.0E)
+
+[DVB]
+0=61
+1=3715,H,6111,34,DVB-S,QPSK
+2=3727,V,34286,89,S2,8PSK
+3=3763,V,34286,89,S2,8PSK
+4=3807,V,34286,89,S2,8PSK
+5=3814,H,4213,35,S2,QPSK
+6=3843,V,34286,89,S2,8PSK
+7=3853,H,1445,Auto,DVB-S,QPSK
+8=3857,H,2465,Auto,DVB-S,QPSK
+9=3860,H,3100,34,DVB-S,QPSK
+10=3967,H,9326,Auto,DVB-S,QPSK
+11=3992,H,26000,56,DVB-S,QPSK
+12=4047,V,4444,12,DVB-S,QPSK
+13=4055,V,34286,89,S2,8PSK
+14=4107,H,12780,78,DVB-S,QPSK
+15=10952,V,2700,78,DVB-S,QPSK
+16=10961,V,3000,78,DVB-S,QPSK
+17=10967,V,3000,78,DVB-S,QPSK
+18=10975,V,3200,34,S2,8PSK
+19=10978,V,1591,56,S2,8PSK
+20=10982,V,4800,34,S2,8PSK
+21=10986,V,1600,34,S2,8PSK
+22=10989,V,3200,34,S2,8PSK
+23=10992,V,1600,34,S2,8PSK
+24=10996,V,4800,34,S2,8PSK
+25=10998,H,3333,34,DVB-S,QPSK
+26=11003,V,4800,34,S2,8PSK
+27=11008,V,3200,34,S2,8PSK
+28=11011,V,1600,34,S2,8PSK
+29=11015,V,4800,34,S2,8PSK
+30=11019,V,1600,34,S2,8PSK
+31=11022,V,3200,34,S2,8PSK
+32=11025,V,1600,34,S2,8PSK
+33=11029,V,4820,34,S2,8PSK
+34=11036,H,3000,34,DVB-S,QPSK
+35=11043,H,2300,78,DVB-S,QPSK
+36=11058,V,6111,34,DVB-S,QPSK
+37=11063,H,3100,34,DVB-S,QPSK
+38=11074,H,2300,78,DVB-S,QPSK
+39=11082,H,3333,34,DVB-S,QPSK
+40=11085,H,2700,78,DVB-S,QPSK
+41=11088,H,2800,78,DVB-S,QPSK
+42=11091,H,3400,34,DVB-S,QPSK
+43=11122,H,2600,34,S2,8PSK
+44=11165,H,2300,78,DVB-S,QPSK
+45=11168,H,2500,78,DVB-S,QPSK
+46=11172,H,2190,78,DVB-S,QPSK
+47=11467,H,12500,34,S2,8PSK
+48=11509,H,7500,34,S2,8PSK
+49=11513,V,2300,34,S2,8PSK
+50=11518,H,7500,34,S2,8PSK
+51=11522,V,2200,78,DVB-S,QPSK
+52=11555,V,30000,23,S2,8PSK
+53=11555,H,28900,34,S2,8PSK
+54=11587,V,5632,34,DVB-S,QPSK
+55=11595,H,31003,78,DVB-S,QPSK
+56=11625,V,1550,78,DVB-S,QPSK
+57=11662,H,7500,56,S2,QPSK
+58=11674,H,2200,78,DVB-S,QPSK
+59=11680,H,10000,34,S2,8PSK
+60=11683,V,15000,56,S2,8PSK
+61=11688,H,7500,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini
new file mode 100644
index 000000000..324d99e83
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0642.ini
@@ -0,0 +1,28 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0642
+2=Intelsat 906 (64.2E)
+
+[DVB]
+0=19
+1=3644,V,8545,23,DVB-S,QPSK
+2=3654,V,5632,34,DVB-S,QPSK
+3=3721,V,4882,23,DVB-S,QPSK
+4=3760,H,2790,78,DVB-S,QPSK
+5=3765,V,1413,34,S2,QPSK
+6=3884,H,4900,12,DVB-S,QPSK
+7=3893,H,3072,12,DVB-S,QPSK
+8=3900,H,3800,12,DVB-S,QPSK
+9=4039,H,2034,23,DVB-S,QPSK
+10=4044,H,2848,Auto,DVB-S,QPSK
+11=4066,H,2848,23,DVB-S,QPSK
+12=4094,H,3680,23,DVB-S,QPSK
+13=4185,V,2532,34,DVB-S,QPSK
+14=10990,V,53000,34,S2,QPSK
+15=11127,V,4000,34,DVB-S,QPSK
+16=11134,V,4000,34,DVB-S,QPSK
+17=11140,V,4000,34,DVB-S,QPSK
+18=11146,V,4000,34,DVB-S,QPSK
+19=11152,V,4000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini
new file mode 100644
index 000000000..81021a0b2
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0650.ini
@@ -0,0 +1,15 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0650
+2=Amos 4 (65.0E)
+
+[DVB]
+0=6
+1=10736,V,45000,23,S2,QPSK
+2=10790,V,45000,23,S2,QPSK
+3=10861,V,45000,12,S2,QPSK
+4=10915,V,45000,12,S2,QPSK
+5=11236,V,45000,12,S2,QPSK
+6=11290,V,45000,12,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini
new file mode 100644
index 000000000..a118dfa38
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0660.ini
@@ -0,0 +1,39 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0660
+2=Intelsat 17 (66.0E)
+
+[DVB]
+0=30
+1=3845,H,30000,34,S2,8PSK
+2=3845,V,27692,78,DVB-S,QPSK
+3=3876,H,14300,34,S2,8PSK
+4=3885,V,30000,34,S2,8PSK
+5=3894,H,13840,56,S2,8PSK
+6=3914,H,11200,34,S2,8PSK
+7=3925,V,30000,34,S2,8PSK
+8=3966,H,14400,23,S2,8PSK
+9=3968,V,8800,23,S2,8PSK
+10=3984,H,14400,23,S2,8PSK
+11=4006,H,14400,23,S2,8PSK
+12=4015,V,30000,34,S2,8PSK
+13=4024,H,14400,23,S2,8PSK
+14=4121,H,7200,34,S2,QPSK
+15=10962,H,3100,Auto,DVB-S,QPSK
+16=11011,H,2811,34,DVB-S,QPSK
+17=11498,H,2400,Auto,DVB-S,QPSK
+18=11505,H,13271,34,DVB-S,QPSK
+19=11515,H,1735,Auto,DVB-S,QPSK
+20=11519,H,3255,34,DVB-S,QPSK
+21=11527,H,3094,Auto,DVB-S,QPSK
+22=11556,H,20129,12,S2,QPSK
+23=12602,H,2000,56,S2,QPSK
+24=12605,H,1025,78,DVB-S,QPSK
+25=12613,H,3965,78,DVB-S,QPSK
+26=12648,H,3900,78,DVB-S,QPSK
+27=12652,H,3900,78,DVB-S,QPSK
+28=12687,H,3400,78,DVB-S,QPSK
+29=12703,H,3400,78,DVB-S,QPSK
+30=12708,H,3400,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini
new file mode 100644
index 000000000..7c2cab681
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0685.ini
@@ -0,0 +1,110 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0685
+2=Intelsat 20 (68.5E)
+
+[DVB]
+0=101
+1=3708,V,7900,34,S2,8PSK
+2=3712,H,14454,34,S2,QPSK
+3=3723,V,9600,34,S2,8PSK
+4=3732,V,7200,34,S2,8PSK
+5=3739,H,26590,12,DVB-S,QPSK
+6=3742,V,7000,34,S2,8PSK
+7=3752,V,9300,34,S2,8PSK
+8=3765,V,2950,56,DVB-S,QPSK
+9=3774,V,2944,34,DVB-S,QPSK
+10=3777,V,2940,34,DVB-S,QPSK
+11=3782,V,2965,34,DVB-S,QPSK
+12=3790,H,7200,34,S2,8PSK
+13=3790,V,1681,34,S2,QPSK
+14=3796,V,7300,34,S2,8PSK
+15=3802,H,10000,34,DVB-S,QPSK
+16=3802,V,1954,34,DVB-S,QPSK
+17=3810,H,3312,23,DVB-S,QPSK
+18=3828,V,7200,23,S2,8PSK
+19=3836,V,7200,23,S2,8PSK
+20=3838,H,16296,34,DVB-S,QPSK
+21=3845,V,6111,34,DVB-S,QPSK
+22=3854,V,7500,34,DVB-S,QPSK
+23=3863,V,6111,34,DVB-S,QPSK
+24=3867,V,9875,34,S2,8PSK
+25=3873,V,7200,34,DVB-S,QPSK
+26=3887,V,2960,34,DVB-S,QPSK
+27=3891,V,1954,56,DVB-S,QPSK
+28=3900,H,22222,56,DVB-S,QPSK
+29=3900,V,10370,34,DVB-S,QPSK
+30=3913,V,6510,34,DVB-S,QPSK
+31=3919,H,1600,56,S2,QPSK
+32=3922,H,3200,56,S2,QPSK
+33=3922,V,7000,56,S2,QPSK
+34=3930,H,9600,56,S2,QPSK
+35=3940,V,7200,34,S2,QPSK
+36=3974,H,19500,34,DVB-S,QPSK
+37=3974,V,19850,34,DVB-S,QPSK
+38=3994,H,4000,23,DVB-S,QPSK
+39=3996,V,6666,34,DVB-S,QPSK
+40=4000,H,6500,34,DVB-S,QPSK
+41=4003,V,7200,34,S2,8PSK
+42=4006,H,2990,34,DVB-S,QPSK
+43=4013,H,7200,34,S2,8PSK
+44=4013,V,6111,34,DVB-S,QPSK
+45=4034,H,20500,23,DVB-S,QPSK
+46=4036,V,21600,56,S2,QPSK
+47=4054,V,4400,34,DVB-S,QPSK
+48=4059,V,3529,34,DVB-S,QPSK
+49=4064,H,19850,78,DVB-S,QPSK
+50=4064,V,4400,34,DVB-S,QPSK
+51=4070,V,4340,34,DVB-S,QPSK
+52=4076,V,3600,34,S2,8PSK
+53=4085,V,7020,34,DVB-S,QPSK
+54=4090,H,14368,34,S2,8PSK
+55=4092,V,2963,34,DVB-S,QPSK
+56=4103,H,5720,34,DVB-S,QPSK
+57=4103,V,7800,34,S2,8PSK
+58=4117,H,3333,23,DVB-S,QPSK
+59=4118,V,8800,Auto,S2,8PSK
+60=4130,H,6400,34,S2,8PSK
+61=4130,V,10369,34,DVB-S,QPSK
+62=4150,H,15000,23,S2,8PSK
+63=4155,V,22500,56,S2,8PSK
+64=4163,H,7200,34,S2,QPSK
+65=4184,V,21600,56,S2,8PSK
+66=10970,V,30000,56,DVB-S,QPSK
+67=10970,H,30000,56,DVB-S,QPSK
+68=11010,V,30000,56,DVB-S,QPSK
+69=11010,H,30000,56,DVB-S,QPSK
+70=11014,V,3750,34,S2,8PSK
+71=11050,V,30000,23,S2,8PSK
+72=11050,H,30000,56,DVB-S,QPSK
+73=11090,V,30000,56,DVB-S,QPSK
+74=11090,H,30000,56,DVB-S,QPSK
+75=11092,H,1024,34,DVB-S,QPSK
+76=11130,V,30000,56,DVB-S,QPSK
+77=11130,H,30000,56,DVB-S,QPSK
+78=11170,V,28800,56,S2,8PSK
+79=11170,H,30000,56,DVB-S,QPSK
+80=11474,H,30000,56,DVB-S,QPSK
+81=11477,V,2170,34,DVB-S,QPSK
+82=11514,V,28750,12,S2,QPSK
+83=11514,H,30000,23,S2,8PSK
+84=11554,V,30000,23,S2,8PSK
+85=11554,H,30000,23,S2,8PSK
+86=11594,V,27500,56,DVB-S,QPSK
+87=11594,H,30000,56,DVB-S,QPSK
+88=11634,V,30000,56,DVB-S,QPSK
+89=11634,H,30000,23,S2,8PSK
+90=11674,H,30000,56,DVB-S,QPSK
+91=12522,V,27500,34,DVB-S,QPSK
+92=12562,H,26657,23,DVB-S,QPSK
+93=12567,V,3100,34,DVB-S,QPSK
+94=12574,V,9700,12,DVB-S,QPSK
+95=12602,V,26657,23,DVB-S,QPSK
+96=12638,V,4690,34,DVB-S,QPSK
+97=12657,V,4883,34,DVB-S,QPSK
+98=12682,V,30000,23,DVB-S,QPSK
+99=12682,H,26657,23,DVB-S,QPSK
+100=12722,V,26657,12,DVB-S,QPSK
+101=12722,H,26657,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini
new file mode 100644
index 000000000..0af8237c9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0705.ini
@@ -0,0 +1,20 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0705
+2=Eutelsat 70B (70.5E)
+
+[DVB]
+0=11
+1=11092,V,1028,34,DVB-S,QPSK
+2=11211,H,5110,12,DVB-S,QPSK
+3=11213,V,16667,56,S2,8PSK
+4=11255,V,4832,Auto,S2,QPSK
+5=11294,H,44900,23,S2,QPSK
+6=11356,V,44900,34,S2,QPSK
+7=11477,V,2170,12,S2,QPSK
+8=11490,V,2150,23,S2,QPSK
+9=11520,V,3332,12,S2,QPSK
+10=11555,H,3034,12,S2,QPSK
+11=11565,H,11401,Auto,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini
new file mode 100644
index 000000000..c25a6ecf5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0721.ini
@@ -0,0 +1,14 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0721
+2=Intelsat 22 (72.1E)
+
+[DVB]
+0=5
+1=3724,H,16073,34,S2,8PSK
+2=3735,H,2325,23,S2,8PSK
+3=3754,H,7500,34,DVB-S,QPSK
+4=4067,V,6111,34,DVB-S,QPSK
+5=12541,H,2300,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini
new file mode 100644
index 000000000..91356547c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0740.ini
@@ -0,0 +1,47 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0740
+2=Insat 3C/4CR (74.0E)
+
+[DVB]
+0=38
+1=3740,V,2500,34,DVB-S,QPSK
+2=3745,V,2500,34,DVB-S,QPSK
+3=3752,V,2500,34,DVB-S,QPSK
+4=3756,V,2500,34,DVB-S,QPSK
+5=3776,V,3800,34,DVB-S,QPSK
+6=3780,H,6250,34,DVB-S,QPSK
+7=3781,V,2000,34,DVB-S,QPSK
+8=3788,V,3800,34,DVB-S,QPSK
+9=3796,V,3800,34,DVB-S,QPSK
+10=3801,V,3800,34,DVB-S,QPSK
+11=3868,H,2250,34,DVB-S,QPSK
+12=3871,H,2250,34,DVB-S,QPSK
+13=3874,H,1923,34,DVB-S,QPSK
+14=3879,H,2200,34,DVB-S,QPSK
+15=3884,H,2250,34,DVB-S,QPSK
+16=3889,H,2250,34,DVB-S,QPSK
+17=3895,H,2000,34,DVB-S,QPSK
+18=3898,H,1500,34,DVB-S,QPSK
+19=3901,H,1500,34,DVB-S,QPSK
+20=4165,H,26000,12,DVB-S,QPSK
+21=11513,H,3000,23,DVB-S,QPSK
+22=11520,H,1700,34,DVB-S,QPSK
+23=11523,H,1700,34,DVB-S,QPSK
+24=11526,H,1700,34,DVB-S,QPSK
+25=11578,H,5000,78,DVB-S,QPSK
+26=11587,V,4000,78,DVB-S,QPSK
+27=11592,V,2000,34,DVB-S,QPSK
+28=11597,H,2000,34,DVB-S,QPSK
+29=11599,V,1800,34,DVB-S,QPSK
+30=11603,V,2000,34,DVB-S,QPSK
+31=11607,V,2000,34,DVB-S,QPSK
+32=11656,V,3333,34,DVB-S,QPSK
+33=11667,V,3000,34,DVB-S,QPSK
+34=11672,V,2500,34,DVB-S,QPSK
+35=11680,H,1400,34,DVB-S,QPSK
+36=11680,V,2965,34,DVB-S,QPSK
+37=11683,H,1600,34,DVB-S,QPSK
+38=11685,V,2900,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini
new file mode 100644
index 000000000..8cdc07590
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0750.ini
@@ -0,0 +1,44 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0750
+2=ABS 2 (75.0E)
+
+[DVB]
+0=35
+1=3545,H,1956,34,S2,QPSK
+2=3590,V,1850,34,DVB-S,QPSK
+3=3618,V,29000,56,S2,QPSK
+4=3766,V,3000,34,DVB-S,QPSK
+5=3770,V,2142,23,S2,8PSK
+6=3772,V,2400,23,S2,QPSK
+7=3779,V,7495,34,DVB-S,QPSK
+8=3781,V,35342,23,S2,QPSK
+9=3791,V,3703,23,DVB-S,QPSK
+10=3846,V,2300,34,DVB-S,QPSK
+11=3942,V,30000,23,S2,QPSK
+12=3978,V,29000,56,S2,QPSK
+13=4123,V,2800,56,S2,8PSK
+14=10985,H,35007,34,S2,8PSK
+15=11045,H,44922,56,DVB-S,QPSK
+16=11105,H,43200,56,DVB-S,QPSK
+17=11473,V,22500,34,S2,8PSK
+18=11491,V,4650,23,S2,8PSK
+19=11505,V,3400,78,DVB-S,QPSK
+20=11531,V,22000,56,DVB-S,QPSK
+21=11559,V,22000,56,DVB-S,QPSK
+22=11605,V,43200,78,DVB-S,QPSK
+23=11665,V,44922,56,DVB-S,QPSK
+24=11733,V,43000,56,DVB-S,QPSK
+25=11734,H,44000,23,DVB-S,QPSK
+26=11790,H,44000,23,DVB-S,QPSK
+27=11793,V,43200,56,DVB-S,QPSK
+28=11853,V,45000,23,S2,8PSK
+29=11913,V,45000,23,S2,8PSK
+30=11973,V,45000,23,S2,8PSK
+31=12033,V,45000,23,S2,8PSK
+32=12093,V,45000,23,S2,8PSK
+33=12153,V,45000,23,S2,8PSK
+34=12153,H,41900,45,S2,QPSK
+35=12524,H,30000,12,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini
new file mode 100644
index 000000000..1a6195f9a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0765.ini
@@ -0,0 +1,85 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0765
+2=Apstar 7 (76.5E)
+
+[DVB]
+0=76
+1=3629,H,1489,34,S2,QPSK
+2=3638,H,1600,35,S2,8PSK
+3=3685,V,3333,34,DVB-S,QPSK
+4=3690,H,13000,34,S2,8PSK
+5=3705,V,8888,23,S2,8PSK
+6=3720,H,29620,34,S2,8PSK
+7=3747,H,2500,34,DVB-S,QPSK
+8=3753,H,2400,34,DVB-S,QPSK
+9=3757,H,4440,34,S2,QPSK
+10=3769,H,13333,56,DVB-S,QPSK
+11=3780,V,30000,34,S2,8PSK
+12=3787,H,4600,23,DVB-S,QPSK
+13=3793,H,4443,34,DVB-S,QPSK
+14=3805,H,4800,34,S2,8PSK
+15=3812,H,2200,34,S2,8PSK
+16=3815,H,3333,34,DVB-S,QPSK
+17=3824,H,2400,34,DVB-S,QPSK
+18=3832,V,6111,34,DVB-S,QPSK
+19=3835,H,3256,34,DVB-S,QPSK
+20=3840,H,3000,34,DVB-S,QPSK
+21=3847,H,5357,78,DVB-S,QPSK
+22=3847,V,7857,56,S2,QPSK
+23=3852,H,3000,34,DVB-S,QPSK
+24=3857,H,3200,Auto,S2,8PSK
+25=3880,H,30000,34,S2,8PSK
+26=3914,V,3255,34,DVB-S,QPSK
+27=3920,H,28340,56,DVB-S,QPSK
+28=3932,V,1480,34,DVB-S,QPSK
+29=3951,V,1480,34,DVB-S,QPSK
+30=3960,H,30000,34,S2,8PSK
+31=3985,H,3700,34,DVB-S,QPSK
+32=3990,H,4300,34,S2,QPSK
+33=3998,H,3200,34,DVB-S,QPSK
+34=4003,H,4340,34,DVB-S,QPSK
+35=4009,H,4300,34,DVB-S,QPSK
+36=4016,H,4340,34,DVB-S,QPSK
+37=4019,V,2222,23,S2,QPSK
+38=4022,V,2961,12,DVB-S,QPSK
+39=4026,H,4800,34,DVB-S,QPSK
+40=4034,H,4300,34,DVB-S,QPSK
+41=4038,H,1600,23,S2,8PSK
+42=4041,H,1600,23,S2,QPSK
+43=4044,H,1600,23,S2,QPSK
+44=4048,V,2450,23,S2,8PSK
+45=4050,H,4300,34,DVB-S,QPSK
+46=4056,H,3600,35,S2,8PSK
+47=4059,V,7857,56,S2,QPSK
+48=4063,H,1250,34,DVB-S,QPSK
+49=4067,H,2500,89,S2,QPSK
+50=4079,H,1600,34,S2,QPSK
+51=4082,H,2857,23,S2,8PSK
+52=4088,V,7750,56,S2,8PSK
+53=4104,H,5000,34,S2,QPSK
+54=4110,H,4600,34,DVB-S,QPSK
+55=4117,H,4285,34,DVB-S,QPSK
+56=4125,H,4441,34,DVB-S,QPSK
+57=4129,V,11395,34,DVB-S,QPSK
+58=4131,H,3600,34,DVB-S,QPSK
+59=4135,H,3333,34,DVB-S,QPSK
+60=4151,H,14670,34,S2,8PSK
+61=4188,V,3200,34,DVB-S,QPSK
+62=10973,V,24500,23,S2,QPSK
+63=11010,V,30000,12,DVB-S,QPSK
+64=11052,V,30000,23,DVB-S,QPSK
+65=11105,V,45000,23,DVB-S,QPSK
+66=11167,V,45000,23,DVB-S,QPSK
+67=11532,H,3732,56,S2,8PSK
+68=11536,H,3732,56,S2,8PSK
+69=11541,H,3450,34,S2,8PSK
+70=11547,H,2500,34,S2,QPSK
+71=11568,H,3330,34,S2,8PSK
+72=11596,H,3732,56,S2,8PSK
+73=12531,V,15000,34,S2,QPSK
+74=12604,V,30000,56,S2,QPSK
+75=12638,V,15000,34,S2,8PSK
+76=12719,V,45000,56,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini
new file mode 100644
index 000000000..8dcf19d37
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0785.ini
@@ -0,0 +1,112 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0785
+2=Thaicom 5/6 (78.5E)
+
+[DVB]
+0=103
+1=3408,V,2916,34,DVB-S,QPSK
+2=3414,V,2916,34,DVB-S,QPSK
+3=3418,V,3750,34,S2,QPSK
+4=3422,V,2222,34,DVB-S,QPSK
+5=3425,V,2592,12,DVB-S,QPSK
+6=3433,V,5000,34,DVB-S,QPSK
+7=3438,V,2915,34,DVB-S,QPSK
+8=3440,H,26666,34,DVB-S,QPSK
+9=3441,V,1556,34,DVB-S,QPSK
+10=3444,V,1630,34,DVB-S,QPSK
+11=3450,V,2500,34,DVB-S,QPSK
+12=3454,V,3333,34,DVB-S,QPSK
+13=3457,V,2857,34,DVB-S,QPSK
+14=3462,V,2857,34,DVB-S,QPSK
+15=3480,H,30000,56,DVB-S,QPSK
+16=3515,V,2917,34,DVB-S,QPSK
+17=3520,H,28125,34,DVB-S,QPSK
+18=3545,V,30000,56,DVB-S,QPSK
+19=3551,H,13333,34,DVB-S,QPSK
+20=3563,H,5555,35,S2,8PSK
+21=3574,H,6510,34,DVB-S,QPSK
+22=3585,V,30000,56,DVB-S,QPSK
+23=3600,H,26667,34,DVB-S,QPSK
+24=3625,V,30000,34,S2,8PSK
+25=3640,H,28066,34,DVB-S,QPSK
+26=3665,H,3704,34,DVB-S,QPSK
+27=3683,H,7500,34,S2,8PSK
+28=3690,H,2417,78,DVB-S,QPSK
+29=3696,H,4167,35,S2,8PSK
+30=3703,V,3333,78,DVB-S,QPSK
+31=3709,H,13333,23,S2,8PSK
+32=3711,V,1458,78,DVB-S,QPSK
+33=3715,V,1481,34,DVB-S,QPSK
+34=3718,V,1600,34,DVB-S,QPSK
+35=3719,H,2500,23,S2,8PSK
+36=3731,H,12500,78,DVB-S,QPSK
+37=3745,V,4688,34,DVB-S,QPSK
+38=3749,V,4688,34,DVB-S,QPSK
+39=3757,V,4688,34,DVB-S,QPSK
+40=3758,H,28066,34,DVB-S,QPSK
+41=3760,H,30000,56,DVB-S,QPSK
+42=3784,V,4262,34,DVB-S,QPSK
+43=3792,V,4262,34,DVB-S,QPSK
+44=3797,V,4262,34,DVB-S,QPSK
+45=3800,H,30000,56,DVB-S,QPSK
+46=3803,V,4551,34,DVB-S,QPSK
+47=3809,V,4550,34,DVB-S,QPSK
+48=3826,H,4700,34,DVB-S,QPSK
+49=3834,H,8000,56,S2,8PSK
+50=3840,V,30000,56,DVB-S,QPSK
+51=3841,H,2900,34,DVB-S,QPSK
+52=3847,H,4700,34,DVB-S,QPSK
+53=3851,H,2900,34,DVB-S,QPSK
+54=3880,H,30000,34,DVB-S,QPSK
+55=3910,V,14650,45,S2,QPSK
+56=3920,H,30000,34,DVB-S,QPSK
+57=3930,V,15000,56,S2,QPSK
+58=3949,V,2550,78,DVB-S,QPSK
+59=3975,V,2500,35,S2,8PSK
+60=3990,V,12000,23,S2,8PSK
+61=4000,V,4815,34,DVB-S,QPSK
+62=4000,H,30000,23,S2,8PSK
+63=4005,V,4815,34,DVB-S,QPSK
+64=4017,V,1800,34,DVB-S,QPSK
+65=4040,H,30000,23,S2,8PSK
+66=4053,V,8333,34,DVB-S,QPSK
+67=4080,H,30000,35,S2,8PSK
+68=4091,V,2000,34,DVB-S,QPSK
+69=4096,V,5295,34,DVB-S,QPSK
+70=4120,V,30000,910,S2,QPSK
+71=4120,H,30000,56,DVB-S,QPSK
+72=4144,H,2530,34,DVB-S,QPSK
+73=4148,H,4688,34,DVB-S,QPSK
+74=4154,H,3125,34,DVB-S,QPSK
+75=4157,H,2530,34,DVB-S,QPSK
+76=4160,V,30000,56,DVB-S,QPSK
+77=4160,H,2530,34,DVB-S,QPSK
+78=4163,H,2530,34,DVB-S,QPSK
+79=4167,H,2530,34,DVB-S,QPSK
+80=4170,H,2530,34,DVB-S,QPSK
+81=4173,H,2530,34,DVB-S,QPSK
+82=4177,H,2530,34,DVB-S,QPSK
+83=12272,H,30000,23,DVB-S,QPSK
+84=12313,H,30000,23,DVB-S,QPSK
+85=12313,V,30000,34,DVB-S,QPSK
+86=12355,H,30000,56,DVB-S,QPSK
+87=12355,V,30000,23,S2,8PSK
+88=12396,H,30000,35,S2,8PSK
+89=12405,V,45000,34,S2,8PSK
+90=12438,H,30000,23,DVB-S,QPSK
+91=12467,V,45000,34,DVB-S,QPSK
+92=12479,H,30000,35,S2,8PSK
+93=12521,H,30000,35,S2,8PSK
+94=12521,V,30000,34,S2,8PSK
+95=12562,H,25776,23,DVB-S,QPSK
+96=12562,V,30000,34,S2,8PSK
+97=12604,H,30000,56,DVB-S,8PSK
+98=12604,V,30000,34,DVB-S,QPSK
+99=12645,V,30000,23,S2,8PSK
+100=12657,H,45000,34,S2,8PSK
+101=12687,V,30000,23,DVB-S,QPSK
+102=12720,H,45000,34,S2,8PSK
+103=12728,V,30000,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini
new file mode 100644
index 000000000..ac7588e57
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0830.ini
@@ -0,0 +1,74 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0830
+2=G-Sat 10/Insat 4A (83.0E)
+
+[DVB]
+0=65
+1=3725,H,26666,34,DVB-S,QPSK
+2=3756,H,13333,34,DVB-S,QPSK
+3=3756,V,3200,Auto,DVB-S,QPSK
+4=3767,H,3000,34,S2,QPSK
+5=3774,V,4250,Auto,DVB-S,QPSK
+6=3777,H,10900,34,DVB-S,QPSK
+7=3805,H,28500,78,DVB-S,QPSK
+8=3828,H,3200,34,DVB-S,QPSK
+9=3832,H,2100,34,DVB-S,QPSK
+10=3836,H,1800,34,DVB-S,QPSK
+11=3841,H,6920,78,DVB-S,QPSK
+12=3847,H,3333,34,DVB-S,QPSK
+13=3860,H,6920,34,DVB-S,QPSK
+14=3868,H,3000,34,DVB-S,QPSK
+15=3874,H,3400,34,S2,8PSK
+16=3880,H,4600,34,DVB-S,QPSK
+17=3884,H,1500,34,DVB-S,QPSK
+18=3888,H,1071,34,DVB-S,QPSK
+19=3892,H,3300,34,DVB-S,QPSK
+20=3898,H,6800,34,DVB-S,QPSK
+21=3909,H,4000,34,S2,8PSK
+22=3921,H,13000,78,DVB-S,QPSK
+23=3936,H,10100,78,DVB-S,QPSK
+24=3949,H,3673,56,S2,8PSK
+25=3958,H,9500,78,DVB-S,QPSK
+26=3968,H,2000,34,DVB-S,QPSK
+27=3976,H,3200,34,DVB-S,QPSK
+28=3979,H,1451,34,DVB-S,QPSK
+29=3983,H,1451,34,DVB-S,QPSK
+30=3990,H,2140,34,DVB-S,QPSK
+31=4004,H,22220,56,DVB-S,QPSK
+32=4020,H,2140,34,DVB-S,QPSK
+33=4030,H,4440,34,DVB-S,QPSK
+34=4040,H,7500,78,DVB-S,QPSK
+35=4054,H,13230,34,DVB-S,QPSK
+36=4072,H,6500,34,DVB-S,QPSK
+37=4076,H,1500,34,DVB-S,QPSK
+38=4080,H,2000,34,DVB-S,QPSK
+39=4083,H,2100,34,DVB-S,QPSK
+40=4087,H,3300,34,DVB-S,QPSK
+41=4091,H,3000,34,DVB-S,QPSK
+42=4096,H,2170,23,S2,8PSK
+43=4100,H,4750,34,DVB-S,QPSK
+44=4109,H,1800,34,DVB-S,QPSK
+45=4115,H,7776,34,DVB-S,QPSK
+46=4122,H,1800,34,DVB-S,QPSK
+47=4133,H,11888,34,S2,8PSK
+48=4142,H,1255,34,DVB-S,QPSK
+49=4151,H,6500,34,DVB-S,QPSK
+50=4161,H,6500,34,DVB-S,QPSK
+51=4170,H,4650,34,DVB-S,QPSK
+52=4175,H,2977,56,DVB-S,QPSK
+53=4180,H,3233,34,DVB-S,QPSK
+54=10970,H,32000,23,S2,8PSK
+55=11010,H,27500,34,DVB-S,8PSK
+56=11050,H,32000,23,S2,8PSK
+57=11090,H,32000,23,S2,8PSK
+58=11130,H,32000,23,S2,8PSK
+59=11170,H,32000,23,DVB-S,8PSK
+60=11470,H,32000,23,S2,8PSK
+61=11510,H,32000,23,S2,8PSK
+62=11550,H,32000,23,S2,8PSK
+63=11590,H,32000,23,S2,8PSK
+64=11630,H,32000,23,S2,8PSK
+65=11670,H,32000,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini
new file mode 100644
index 000000000..faefe54dc
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0851.ini
@@ -0,0 +1,38 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0851
+2=Horizons 2/Intelsat 15 (85.1E)
+
+[DVB]
+0=29
+1=10969,H,1800,34,S2,8PSK
+2=10980,H,2220,34,DVB-S,QPSK
+3=11466,H,2000,56,S2,8PSK
+4=11468,H,2000,56,S2,8PSK
+5=11470,H,1100,56,S2,8PSK
+6=11479,H,2200,34,DVB-S,QPSK
+7=11483,H,1800,56,DVB-S,QPSK
+8=11559,H,2200,78,DVB-S,QPSK
+9=11588,H,2500,34,DVB-S,QPSK
+10=11594,H,2500,34,DVB-S,QPSK
+11=11687,H,2000,89,S2,8PSK
+12=11720,H,28800,34,DVB-S,QPSK
+13=11760,H,28800,23,S2,8PSK
+14=11800,H,28800,23,S2,8PSK
+15=11840,H,28800,23,S2,8PSK
+16=11872,H,15000,12,DVB-S,8PSK
+17=11920,H,28800,23,S2,8PSK
+18=11960,H,28800,35,S2,8PSK
+19=12000,H,28000,23,DVB-S,QPSK
+20=12040,H,28800,34,DVB-S,QPSK
+21=12080,H,26700,35,S2,8PSK
+22=12120,H,26700,35,S2,8PSK
+23=12160,H,28800,35,S2,8PSK
+24=12504,V,4217,34,DVB-S,QPSK
+25=12510,V,3700,78,DVB-S,QPSK
+26=12515,V,3353,34,S2,8PSK
+27=12560,V,30000,56,DVB-S,QPSK
+28=12600,V,30000,23,S2,8PSK
+29=12640,V,30000,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini
new file mode 100644
index 000000000..f5a946f00
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0865.ini
@@ -0,0 +1,30 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0865
+2=KazSat 2 (86.5E)
+
+[DVB]
+0=21
+1=11495,V,8750,89,S2,8PSK
+2=11504,V,6250,89,S2,8PSK
+3=11632,V,1457,89,S2,QPSK
+4=11642,V,1080,34,S2,8PSK
+5=11643,V,1080,34,S2,8PSK
+6=11645,V,1080,34,S2,8PSK
+7=11646,V,1080,34,S2,8PSK
+8=11647,V,1080,34,S2,8PSK
+9=11649,V,1080,34,S2,8PSK
+10=11650,V,1080,34,S2,8PSK
+11=11651,V,1080,34,S2,8PSK
+12=11653,V,1080,34,S2,8PSK
+13=11654,V,1080,34,S2,8PSK
+14=11656,V,2100,34,S2,8PSK
+15=11658,V,1080,34,S2,8PSK
+16=11660,V,2100,34,S2,8PSK
+17=11663,V,5500,56,S2,8PSK
+18=11672,V,5500,34,S2,8PSK
+19=11678,V,5500,56,S2,8PSK
+20=11683,V,5500,56,S2,8PSK
+21=11689,V,5500,56,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini
new file mode 100644
index 000000000..3f856ba71
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0875.ini
@@ -0,0 +1,13 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0875
+2=ChinaSat 12 (87.5E)
+
+[DVB]
+0=4
+1=3774,H,1800,34,S2,QPSK
+2=4035,H,1200,34,DVB-S,QPSK
+3=4067,H,1500,56,S2,QPSK
+4=4140,V,28800,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini
new file mode 100644
index 000000000..a2716d762
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0880.ini
@@ -0,0 +1,34 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0880
+2=ST 2 (88.0E)
+
+[DVB]
+0=25
+1=3629,H,24700,34,S2,8PSK
+2=3632,V,30000,34,S2,8PSK
+3=3657,H,3000,34,DVB-S,QPSK
+4=3671,H,9256,34,DVB-S,QPSK
+5=11062,V,1000,89,S2,8PSK
+6=11066,V,2000,56,DVB-S,QPSK
+7=11164,H,44995,23,S2,8PSK
+8=11164,V,44995,23,S2,8PSK
+9=11483,V,44995,23,S2,8PSK
+10=11483,H,44995,23,S2,8PSK
+11=11546,H,44995,23,S2,8PSK
+12=11546,V,44995,23,S2,8PSK
+13=11609,V,43975,23,S2,8PSK
+14=11609,H,44995,23,S2,8PSK
+15=11633,H,30000,56,S2,QPSK
+16=11669,H,30000,56,S2,QPSK
+17=11672,V,44995,23,S2,8PSK
+18=11672,H,44995,23,S2,8PSK
+19=12516,H,10833,34,DVB-S,QPSK
+20=12533,H,9620,34,S2,8PSK
+21=12642,H,24000,34,DVB-S,QPSK
+22=12702,H,20000,34,DVB-S,QPSK
+23=12705,V,2200,56,DVB-S,QPSK
+24=12722,H,2200,56,DVB-S,QPSK
+25=12730,H,3202,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini
new file mode 100644
index 000000000..d423f69b6
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0900.ini
@@ -0,0 +1,59 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0900
+2=Yamal 401 (90.0E)
+
+[DVB]
+0=50
+1=3539,H,2500,34,DVB-S,QPSK
+2=3553,H,20000,34,DVB-S,QPSK
+3=3582,H,2850,34,DVB-S,QPSK
+4=3588,H,4285,34,DVB-S,QPSK
+5=3594,H,2850,34,DVB-S,QPSK
+6=3600,H,5925,34,DVB-S,QPSK
+7=3603,V,3300,34,DVB-S,QPSK
+8=3605,H,2626,34,DVB-S,QPSK
+9=3613,H,4285,34,DVB-S,QPSK
+10=3617,V,1850,34,DVB-S,QPSK
+11=3618,H,3038,34,DVB-S,QPSK
+12=3623,H,4285,34,DVB-S,QPSK
+13=3645,H,28000,34,DVB-S,QPSK
+14=3675,H,17500,34,DVB-S,QPSK
+15=3819,H,13333,34,S2,8PSK
+16=3837,H,14815,34,DVB-S,QPSK
+17=3858,H,1850,78,DVB-S,QPSK
+18=3908,H,2850,34,DVB-S,QPSK
+19=3920,H,3000,34,DVB-S,QPSK
+20=3924,H,2850,34,DVB-S,QPSK
+21=4026,H,14940,35,S2,8PSK
+22=4046,H,15284,34,S2,8PSK
+23=4106,V,14990,34,S2,8PSK
+24=4124,H,14990,34,S2,8PSK
+25=4126,V,15284,34,S2,8PSK
+26=4144,H,15284,34,S2,8PSK
+27=10972,H,11200,34,DVB-S,QPSK
+28=11057,H,22222,34,S2,8PSK
+29=11092,H,30000,34,S2,8PSK
+30=11131,V,11160,23,S2,8PSK
+31=11165,H,25000,23,S2,8PSK
+32=11239,V,2737,34,S2,8PSK
+33=11462,V,1400,78,DVB-S,QPSK
+34=11492,H,6115,34,S2,QPSK
+35=11504,H,2080,34,DVB-S,QPSK
+36=11507,V,7000,56,DVB-S,QPSK
+37=11512,H,6160,Auto,S2,QPSK
+38=11524,V,2000,78,DVB-S,QPSK
+39=11531,V,4280,34,DVB-S,QPSK
+40=11558,H,20000,34,S2,QPSK
+41=11565,V,1980,23,S2,8PSK
+42=11573,V,5000,34,DVB-S,QPSK
+43=11649,H,2170,34,DVB-S,QPSK
+44=11654,H,6500,34,DVB-S,QPSK
+45=11670,H,14400,56,S2,8PSK
+46=11674,V,7800,56,S2,8PSK
+47=12505,V,2020,Auto,S2,8PSK
+48=12533,V,11760,34,S2,QPSK
+49=12718,H,27500,56,S2,8PSK
+50=12718,V,27500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini
new file mode 100644
index 000000000..3c28ff254
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0915.ini
@@ -0,0 +1,84 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0915
+2=Measat 3/3a/3b (91.5E)
+
+[DVB]
+0=75
+1=3464,H,2963,23,DVB-S,QPSK
+2=3469,V,7500,34,S2,8PSK
+3=3472,H,6000,34,DVB-S,QPSK
+4=3475,H,2963,23,DVB-S,QPSK
+5=3480,V,2961,23,DVB-S,QPSK
+6=3481,H,2963,23,DVB-S,QPSK
+7=3485,V,2961,23,DVB-S,QPSK
+8=3492,H,2963,23,DVB-S,QPSK
+9=3606,V,3750,34,DVB-S,QPSK
+10=3625,V,1600,34,DVB-S,QPSK
+11=3638,H,6666,34,DVB-S,QPSK
+12=3641,V,13333,23,S2,8PSK
+13=3650,H,6666,34,DVB-S,QPSK
+14=3705,H,4290,34,DVB-S,QPSK
+15=3708,V,1400,34,S2,QPSK
+16=3710,H,2860,34,DVB-S,QPSK
+17=3717,H,7500,23,S2,8PSK
+18=3718,V,1916,56,S2,QPSK
+19=3720,V,2170,78,DVB-S,QPSK
+20=3724,V,3030,23,S2,8PSK
+21=3727,H,9833,23,S2,8PSK
+22=3760,V,29700,56,S2,8PSK
+23=3786,V,7200,56,S2,QPSK
+24=3795,V,5064,34,S2,QPSK
+25=3802,V,3333,34,DVB-S,QPSK
+26=3805,V,3255,34,S2,QPSK
+27=3814,V,6660,35,S2,8PSK
+28=3840,H,30000,56,S2,8PSK
+29=3840,V,29720,56,S2,8PSK
+30=3880,V,29720,56,S2,8PSK
+31=3904,H,2916,23,S2,8PSK
+32=3918,H,18385,23,S2,8PSK
+33=3920,V,29720,56,S2,8PSK
+34=3960,H,29700,56,S2,8PSK
+35=4000,H,29700,56,S2,8PSK
+36=4040,H,28600,56,S2,8PSK
+37=4120,V,29720,56,S2,8PSK
+38=4120,H,30000,56,S2,8PSK
+39=4147,H,7200,56,S2,QPSK
+40=4153,V,2090,34,S2,QPSK
+41=4164,H,20640,23,S2,8PSK
+42=10852,V,30000,Auto,S2,QPSK
+43=10932,V,30000,Auto,S2,QPSK
+44=10982,V,30000,34,DVB-S,QPSK
+45=11022,V,30000,34,S2,8PSK
+46=11062,V,30000,34,DVB-S,QPSK
+47=11142,V,30000,78,DVB-S,QPSK
+48=11182,V,30000,78,DVB-S,QPSK
+49=11482,V,30000,78,DVB-S,QPSK
+50=11522,V,30000,78,DVB-S,QPSK
+51=11562,V,30000,78,DVB-S,QPSK
+52=11602,V,30000,78,DVB-S,QPSK
+53=11642,V,30000,78,DVB-S,QPSK
+54=11682,V,30000,78,DVB-S,QPSK
+55=12276,V,30000,35,S2,8PSK
+56=12316,H,30000,56,DVB-S,8PSK
+57=12316,V,30000,35,S2,8PSK
+58=12356,V,30000,35,S2,8PSK
+59=12396,V,30000,35,S2,8PSK
+60=12396,H,31000,23,S2,8PSK
+61=12436,V,30000,35,S2,8PSK
+62=12436,H,31000,23,S2,8PSK
+63=12476,V,30000,35,S2,8PSK
+64=12523,V,30000,78,DVB-S,QPSK
+65=12523,H,30000,56,DVB-S,QPSK
+66=12563,V,30000,56,S2,8PSK
+67=12563,H,30000,56,S2,8PSK
+68=12603,V,30000,56,S2,8PSK
+69=12603,H,30000,56,S2,8PSK
+70=12643,V,30000,78,DVB-S,QPSK
+71=12643,H,30000,56,S2,8PSK
+72=12683,V,30000,56,DVB-S,QPSK
+73=12683,H,27500,56,DVB-S,QPSK
+74=12723,V,30000,56,DVB-S,QPSK
+75=12723,H,30000,56,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini
new file mode 100644
index 000000000..1aaa16641
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0922.ini
@@ -0,0 +1,19 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0922
+2=ChinaSat 9 (92.2E)
+
+[DVB]
+0=10
+1=11880,H,28800,34,DVB-S,QPSK
+2=11920,H,28800,34,DVB-S,QPSK
+3=11940,V,28800,34,DVB-S,QPSK
+4=11960,H,28800,34,DVB-S,QPSK
+5=11980,V,28800,34,DVB-S,QPSK
+6=12020,V,28800,34,DVB-S,QPSK
+7=12060,V,28800,34,DVB-S,QPSK
+8=12100,V,28800,34,DVB-S,QPSK
+9=12140,V,28800,34,DVB-S,QPSK
+10=12180,V,28800,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini
new file mode 100644
index 000000000..e47df3277
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0935.ini
@@ -0,0 +1,77 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0935
+2=Insat 3A/4B (93.5E)
+
+[DVB]
+0=68
+1=3725,H,27500,34,DVB-S,QPSK
+2=3732,V,6250,34,DVB-S,QPSK
+3=3740,V,6250,34,DVB-S,QPSK
+4=3750,V,6250,34,DVB-S,QPSK
+5=3750,H,3000,34,DVB-S,QPSK
+6=3756,H,3000,34,DVB-S,QPSK
+7=3758,V,6250,34,DVB-S,QPSK
+8=3762,H,2500,34,DVB-S,QPSK
+9=3768,H,2500,34,DVB-S,QPSK
+10=3772,V,6250,34,DVB-S,QPSK
+11=3774,H,4250,34,DVB-S,QPSK
+12=3780,V,6250,34,DVB-S,QPSK
+13=3780,H,2500,34,DVB-S,QPSK
+14=3790,H,2500,34,DVB-S,QPSK
+15=3791,V,8600,34,DVB-S,QPSK
+16=3797,H,4250,34,DVB-S,QPSK
+17=3800,V,4250,34,DVB-S,QPSK
+18=3802,H,4250,34,DVB-S,QPSK
+19=3808,H,2500,34,DVB-S,QPSK
+20=3812,V,6250,34,DVB-S,QPSK
+21=3815,H,2500,34,DVB-S,QPSK
+22=3821,V,6250,34,DVB-S,QPSK
+23=3822,H,4250,34,DVB-S,QPSK
+24=3831,V,8600,34,DVB-S,QPSK
+25=3832,H,6250,34,DVB-S,QPSK
+26=3840,H,6250,34,DVB-S,QPSK
+27=3841,V,4250,34,DVB-S,QPSK
+28=3848,H,4250,34,DVB-S,QPSK
+29=3855,H,3800,34,DVB-S,QPSK
+30=3860,H,2500,34,DVB-S,QPSK
+31=3888,V,1400,34,DVB-S,QPSK
+32=3891,V,2000,34,DVB-S,QPSK
+33=3894,V,2000,34,DVB-S,QPSK
+34=3894,H,1500,34,DVB-S,QPSK
+35=3897,V,1500,34,DVB-S,QPSK
+36=3907,V,3125,34,DVB-S,QPSK
+37=3910,V,1500,34,DVB-S,QPSK
+38=3913,V,1000,34,DVB-S,QPSK
+39=3916,V,1300,34,DVB-S,QPSK
+40=3919,V,2000,34,DVB-S,QPSK
+41=3922,V,2000,34,DVB-S,QPSK
+42=3925,H,27500,34,DVB-S,QPSK
+43=3932,V,6250,34,DVB-S,QPSK
+44=3940,V,6250,34,DVB-S,QPSK
+45=3950,V,6250,34,DVB-S,QPSK
+46=3958,V,6250,34,DVB-S,QPSK
+47=4086,V,1400,34,DVB-S,QPSK
+48=4092,V,6250,34,DVB-S,QPSK
+49=4101,V,6250,34,DVB-S,QPSK
+50=4109,V,4250,34,DVB-S,QPSK
+51=4115,V,4250,34,DVB-S,QPSK
+52=4120,V,4250,34,DVB-S,QPSK
+53=4132,V,4000,34,DVB-S,QPSK
+54=4136,V,2000,34,DVB-S,QPSK
+55=4141,V,5150,34,DVB-S,QPSK
+56=4148,V,3000,34,DVB-S,QPSK
+57=4151,V,2100,34,DVB-S,QPSK
+58=10990,V,28500,34,DVB-S,QPSK
+59=11030,V,32000,34,S2,8PSK
+60=11053,V,1800,34,DVB-S,QPSK
+61=11070,V,28500,34,DVB-S,QPSK
+62=11110,V,30000,35,S2,8PSK
+63=11150,V,28500,34,DVB-S,QPSK
+64=11197,V,3333,34,DVB-S,QPSK
+65=11490,V,30000,35,S2,8PSK
+66=11508,V,1400,78,DVB-S,QPSK
+67=11528,V,1400,34,DVB-S,QPSK
+68=11570,V,28500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini
new file mode 100644
index 000000000..1b6ba4775
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0950.ini
@@ -0,0 +1,47 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0950
+2=NSS 6/SES 8 (95.0E)
+
+[DVB]
+0=38
+1=10977,V,40000,78,DVB-S,QPSK
+2=11004,V,2355,34,DVB-S,QPSK
+3=11037,H,40700,34,DVB-S,QPSK
+4=11038,V,45000,56,DVB-S,QPSK
+5=11090,H,30000,56,S2,QPSK
+6=11090,V,30000,34,DVB-S,QPSK
+7=11147,V,2750,23,DVB-S,QPSK
+8=11164,V,3300,34,DVB-S,QPSK
+9=11172,H,30000,56,DVB-S,QPSK
+10=11456,H,3125,34,DVB-S,QPSK
+11=11460,H,3125,34,DVB-S,QPSK
+12=11468,H,3000,34,DVB-S,QPSK
+13=11475,H,6111,34,DVB-S,QPSK
+14=11481,H,45000,34,DVB-S,QPSK
+15=11483,H,3125,34,DVB-S,QPSK
+16=11503,H,6111,34,DVB-S,QPSK
+17=11542,V,43200,34,S2,8PSK
+18=11542,H,45000,56,S2,8PSK
+19=11604,V,3200,34,DVB-S,QPSK
+20=11619,H,5000,34,S2,8PSK
+21=11635,H,27500,34,DVB-S,QPSK
+22=11651,V,3333,34,DVB-S,QPSK
+23=11661,H,5632,34,DVB-S,QPSK
+24=11670,V,5000,23,DVB-S,QPSK
+25=11676,V,28800,34,S2,8PSK
+26=11685,V,6600,34,DVB-S,QPSK
+27=11990,H,43000,Auto,DVB-S,QPSK
+28=12110,H,40700,34,DVB-S,QPSK
+29=12170,H,40700,Auto,DVB-S,QPSK
+30=12535,V,43200,34,DVB-S,QPSK
+31=12595,H,43200,34,DVB-S,QPSK
+32=12595,V,43200,34,DVB-S,QPSK
+33=12647,H,30000,Auto,DVB-S,QPSK
+34=12647,V,32700,56,DVB-S,QPSK
+35=12688,H,3270,34,DVB-S,QPSK
+36=12688,V,27500,56,DVB-S,QPSK
+37=12729,H,26400,34,DVB-S,QPSK
+38=12729,V,32700,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini
new file mode 100644
index 000000000..45d28a1fe
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/0965.ini
@@ -0,0 +1,28 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=0965
+2=Express AM33 (96.5E)
+
+[DVB]
+0=19
+1=3675,V,33483,78,DVB-S,QPSK
+2=3758,V,4340,34,DVB-S,QPSK
+3=3808,V,3215,34,DVB-S,QPSK
+4=3817,V,4270,34,DVB-S,QPSK
+5=3838,V,3230,34,DVB-S,QPSK
+6=3843,V,3220,34,DVB-S,QPSK
+7=3875,V,33390,89,S2,8PSK
+8=3925,V,4883,12,DVB-S,QPSK
+9=4108,V,4275,34,DVB-S,QPSK
+10=4114,V,4285,34,DVB-S,QPSK
+11=4175,V,3294,34,DVB-S,QPSK
+12=10980,H,3200,34,DVB-S,QPSK
+13=11000,H,5700,34,DVB-S,QPSK
+14=11006,H,4444,34,DVB-S,QPSK
+15=11028,V,1666,78,DVB-S,QPSK
+16=11053,V,1570,23,S2,8PSK
+17=11055,V,1666,23,S2,8PSK
+18=11116,V,34000,89,S2,8PSK
+19=11117,H,4444,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini
new file mode 100644
index 000000000..fe9374bcf
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1005.ini
@@ -0,0 +1,80 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1005
+2=AsiaSat 5 (100.5E)
+
+[DVB]
+0=71
+1=3660,V,27500,34,DVB-S,QPSK
+2=3668,H,7120,34,DVB-S,QPSK
+3=3674,H,1500,34,DVB-S,QPSK
+4=3678,H,3600,35,S2,QPSK
+5=3686,H,7120,34,S2,8PSK
+6=3693,H,6111,34,DVB-S,QPSK
+7=3700,V,30000,34,S2,8PSK
+8=3707,H,7120,34,S2,8PSK
+9=3717,H,4167,34,DVB-S,QPSK
+10=3730,H,13800,34,S2,8PSK
+11=3733,V,6111,34,DVB-S,QPSK
+12=3744,V,7120,34,S2,8PSK
+13=3754,V,7120,34,S2,8PSK
+14=3760,H,27500,34,DVB-S,QPSK
+15=3765,V,4640,34,S2,8PSK
+16=3770,V,2644,34,S2,QPSK
+17=3774,H,6111,34,DVB-S,QPSK
+18=3776,V,6111,34,DVB-S,QPSK
+19=3786,H,6000,78,DVB-S,QPSK
+20=3794,H,4640,35,S2,8PSK
+21=3799,H,3255,34,DVB-S,QPSK
+22=3816,H,3624,23,S2,8PSK
+23=3820,V,27500,34,DVB-S,QPSK
+24=3840,H,26666,34,S2,8PSK
+25=3854,H,7500,Auto,S2,QPSK
+26=3860,V,30000,23,S2,8PSK
+27=3877,H,7200,Auto,S2,8PSK
+28=3884,H,7200,Auto,S2,QPSK
+29=3886,V,7500,34,DVB-S,QPSK
+30=3895,V,6111,34,DVB-S,QPSK
+31=3908,H,6666,34,DVB-S,QPSK
+32=3913,V,6111,34,DVB-S,QPSK
+33=3915,H,7120,Auto,S2,QPSK
+34=3924,H,7200,Auto,S2,QPSK
+35=3928,V,7200,Auto,S2,QPSK
+36=3935,H,7120,34,S2,8PSK
+37=3937,V,4500,34,DVB-S,QPSK
+38=3945,V,6200,34,DVB-S,QPSK
+39=3953,V,7200,Auto,S2,QPSK
+40=3960,H,30000,56,S2,8PSK
+41=3980,V,29720,56,S2,8PSK
+42=4000,H,28125,34,DVB-S,QPSK
+43=4040,H,29720,56,S2,8PSK
+44=4076,H,7200,Auto,S2,8PSK
+45=4086,H,7200,34,S2,8PSK
+46=4094,H,9874,Auto,S2,QPSK
+47=4114,H,18400,23,S2,8PSK
+48=4132,H,10587,23,S2,QPSK
+49=4148,H,7100,Auto,S2,QPSK
+50=4148,V,11852,34,DVB-S,QPSK
+51=4155,H,6666,34,DVB-S,QPSK
+52=4165,H,6673,Auto,S2,QPSK
+53=4175,H,7200,34,S2,8PSK
+54=12267,V,3000,34,DVB-S,QPSK
+55=12288,V,1330,34,DVB-S,QPSK
+56=12323,V,12000,34,DVB-S,QPSK
+57=12377,V,2000,34,DVB-S,QPSK
+58=12381,V,2000,34,DVB-S,QPSK
+59=12386,V,2000,34,DVB-S,QPSK
+60=12437,V,2590,34,DVB-S,QPSK
+61=12515,H,6200,34,DVB-S,QPSK
+62=12522,V,40700,34,DVB-S,QPSK
+63=12542,H,6111,34,DVB-S,QPSK
+64=12582,H,5632,34,DVB-S,QPSK
+65=12582,V,40700,23,S2,8PSK
+66=12591,H,5632,34,DVB-S,QPSK
+67=12602,H,5632,34,DVB-S,QPSK
+68=12620,H,6300,34,DVB-S,QPSK
+69=12635,H,8880,34,DVB-S,QPSK
+70=12642,V,40700,23,S2,8PSK
+71=12702,V,40700,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini
new file mode 100644
index 000000000..f4607ef89
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1030.ini
@@ -0,0 +1,13 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1030
+2=Express AM3 (103.0E)
+
+[DVB]
+0=4
+1=3610,V,2500,56,S2,QPSK
+2=3675,V,31900,56,S2,8PSK
+3=11606,V,34425,35,S2,8PSK
+4=11669,V,34425,35,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini
new file mode 100644
index 000000000..79c54d9d8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1055.ini
@@ -0,0 +1,57 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1055
+2=AsiaSat 7/8 (105.5E)
+
+[DVB]
+0=48
+1=3683,H,27500,Auto,S2,QPSK
+2=3706,H,6000,34,DVB-S,QPSK
+3=3712,V,9000,35,S2,8PSK
+4=3715,H,8167,34,DVB-S,QPSK
+5=3725,V,4833,45,S2,QPSK
+6=3729,H,13650,34,DVB-S,QPSK
+7=3732,V,6500,34,DVB-S,QPSK
+8=3739,V,2815,34,DVB-S,QPSK
+9=3742,V,1500,34,DVB-S,QPSK
+10=3745,V,2626,34,DVB-S,QPSK
+11=3755,V,4418,78,DVB-S,QPSK
+12=3760,H,26000,78,DVB-S,QPSK
+13=3780,V,28100,34,DVB-S,QPSK
+14=3820,V,27500,34,DVB-S,QPSK
+15=3840,H,29720,56,S2,8PSK
+16=3860,V,28100,56,S2,8PSK
+17=3880,H,27500,34,DVB-S,QPSK
+18=3890,V,11838,35,S2,8PSK
+19=3898,V,2240,35,S2,8PSK
+20=3906,V,2913,34,DVB-S,QPSK
+21=3915,V,7260,56,DVB-S,QPSK
+22=3940,V,28100,56,S2,8PSK
+23=3960,H,27500,34,DVB-S,QPSK
+24=3980,V,28100,34,DVB-S,QPSK
+25=4000,H,26850,78,DVB-S,QPSK
+26=4020,V,27250,34,DVB-S,QPSK
+27=4040,H,26500,12,DVB-S,QPSK
+28=4060,V,26666,34,DVB-S,QPSK
+29=4065,H,4296,34,DVB-S,QPSK
+30=4078,H,3185,78,DVB-S,QPSK
+31=4082,H,3185,56,DVB-S,QPSK
+32=4087,H,3185,34,DVB-S,QPSK
+33=4091,H,2894,34,DVB-S,QPSK
+34=4095,H,2894,34,DVB-S,QPSK
+35=4100,V,29720,56,S2,8PSK
+36=4120,H,27500,78,DVB-S,QPSK
+37=4140,V,27500,34,DVB-S,QPSK
+38=4146,H,5317,34,DVB-S,QPSK
+39=4155,H,9833,35,S2,8PSK
+40=4165,H,5040,34,DVB-S,QPSK
+41=4172,H,2480,34,DVB-S,QPSK
+42=4176,H,2444,34,DVB-S,QPSK
+43=4180,V,26666,34,DVB-S,QPSK
+44=12468,H,4195,34,DVB-S,QPSK
+45=12534,H,3300,34,S2,8PSK
+46=12579,H,4000,34,S2,8PSK
+47=12596,V,30000,56,DVB-S,QPSK
+48=12720,V,30000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini
new file mode 100644
index 000000000..a53b0c2e8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1082.ini
@@ -0,0 +1,99 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1082
+2=NSS 11/SES 7/Telkom 1 (108.2E)
+
+[DVB]
+0=90
+1=2535,H,22500,78,DVB-S,QPSK
+2=2535,V,22500,34,S2,8PSK
+3=2565,H,22500,78,DVB-S,QPSK
+4=2565,V,22500,78,DVB-S,QPSK
+5=2595,H,20000,78,DVB-S,QPSK
+6=2595,V,22500,78,DVB-S,QPSK
+7=2625,H,22500,78,DVB-S,QPSK
+8=2625,V,22500,34,S2,QPSK
+9=2655,H,22500,78,DVB-S,QPSK
+10=2655,V,22500,Auto,S2,8PSK
+11=3483,V,3000,34,DVB-S,QPSK
+12=3515,V,23111,23,S2,QPSK
+13=3552,H,3100,34,DVB-S,QPSK
+14=3580,H,30000,34,S2,8PSK
+15=3600,V,30000,34,S2,8PSK
+16=3620,H,30000,34,S2,8PSK
+17=3640,V,30000,34,S2,8PSK
+18=3707,H,6000,34,S2,8PSK
+19=3722,H,3330,34,DVB-S,QPSK
+20=3727,V,7000,34,DVB-S,QPSK
+21=3732,H,4160,34,DVB-S,QPSK
+22=3735,H,1200,34,DVB-S,QPSK
+23=3745,H,3000,34,DVB-S,QPSK
+24=3776,H,4280,34,DVB-S,QPSK
+25=3787,H,6750,34,DVB-S,QPSK
+26=3793,H,3000,34,DVB-S,QPSK
+27=3797,H,3905,34,DVB-S,QPSK
+28=3802,H,3000,78,DVB-S,QPSK
+29=3812,H,3000,34,DVB-S,QPSK
+30=3817,H,3000,34,DVB-S,QPSK
+31=3830,H,3000,34,DVB-S,QPSK
+32=3880,H,3000,34,S2,8PSK
+33=3890,H,6000,34,DVB-S,QPSK
+34=3895,H,2500,34,DVB-S,QPSK
+35=3913,H,2400,34,DVB-S,QPSK
+36=3916,H,3330,34,DVB-S,QPSK
+37=3920,H,3000,34,DVB-S,QPSK
+38=3947,H,1500,34,DVB-S,QPSK
+39=3960,H,3000,34,DVB-S,QPSK
+40=3971,H,2100,34,DVB-S,QPSK
+41=3981,V,1235,34,DVB-S,QPSK
+42=3990,H,6000,34,DVB-S,QPSK
+43=3998,H,3000,34,DVB-S,QPSK
+44=4004,H,6000,34,DVB-S,QPSK
+45=4014,H,6000,34,DVB-S,QPSK
+46=4029,H,5122,34,DVB-S,QPSK
+47=4036,H,3100,34,DVB-S,QPSK
+48=4040,H,3000,34,DVB-S,QPSK
+49=4079,H,3100,34,DVB-S,QPSK
+50=4086,H,6000,34,DVB-S,QPSK
+51=4092,H,3570,34,DVB-S,QPSK
+52=4097,H,3125,34,DVB-S,QPSK
+53=4130,V,2100,34,DVB-S,QPSK
+54=4159,H,3000,34,DVB-S,QPSK
+55=4163,V,1840,34,DVB-S,QPSK
+56=11480,V,28800,23,S2,8PSK
+57=11481,H,18750,34,S2,8PSK
+58=11483,H,26600,34,S2,8PSK
+59=11510,H,20000,34,S2,8PSK
+60=11520,V,30000,34,S2,8PSK
+61=11520,H,30000,34,S2,8PSK
+62=11560,V,30000,34,S2,8PSK
+63=11560,H,30000,34,S2,8PSK
+64=11568,V,20000,34,S2,8PSK
+65=11568,H,20000,34,S2,8PSK
+66=11598,V,20000,34,S2,8PSK
+67=11598,H,20000,23,S2,8PSK
+68=11600,V,30000,34,S2,8PSK
+69=11600,H,30000,34,S2,8PSK
+70=11627,H,20000,34,S2,8PSK
+71=11640,V,30000,34,S2,8PSK
+72=11640,H,24000,34,S2,8PSK
+73=11656,H,18750,34,DVB-S,QPSK
+74=11680,V,30000,34,S2,8PSK
+75=11685,H,18750,34,DVB-S,QPSK
+76=12328,H,5000,34,DVB-S,QPSK
+77=12401,V,2400,34,S2,8PSK
+78=12406,V,3330,56,DVB-S,QPSK
+79=12421,V,2962,34,DVB-S,QPSK
+80=12427,V,4440,34,DVB-S,QPSK
+81=12431,H,30000,56,DVB-S,QPSK
+82=12434,H,2000,34,DVB-S,QPSK
+83=12439,H,1900,12,DVB-S,QPSK
+84=12444,H,1900,34,DVB-S,QPSK
+85=12447,H,3000,34,DVB-S,QPSK
+86=12471,H,30000,56,DVB-S,QPSK
+87=12486,H,2000,34,DVB-S,QPSK
+88=12651,V,26667,34,DVB-S,QPSK
+89=12711,H,30000,23,S2,8PSK
+90=12731,V,30000,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini
new file mode 100644
index 000000000..789b56cca
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1100.ini
@@ -0,0 +1,33 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1100
+2=BSAT 3A/3C/JCSAT 110R/N-Sat 110 (110.0E)
+
+[DVB]
+0=24
+1=11727,V,28860,23,DVB-S,8PSK
+2=11766,V,28860,23,DVB-S,8PSK
+3=11804,V,28860,23,DVB-S,8PSK
+4=11843,V,28860,23,DVB-S,8PSK
+5=11881,V,28860,23,DVB-S,8PSK
+6=11919,V,28860,23,DVB-S,8PSK
+7=11958,V,28860,23,DVB-S,8PSK
+8=11996,V,28860,23,DVB-S,8PSK
+9=12034,V,28860,23,DVB-S,QPSK
+10=12073,V,28860,23,DVB-S,8PSK
+11=12111,V,28860,23,DVB-S,8PSK
+12=12149,V,28860,23,DVB-S,8PSK
+13=12291,V,28860,23,DVB-S,QPSK
+14=12331,V,28860,23,DVB-S,QPSK
+15=12371,V,28860,23,DVB-S,QPSK
+16=12411,V,28860,23,DVB-S,QPSK
+17=12451,V,28860,23,DVB-S,QPSK
+18=12491,V,28860,23,DVB-S,QPSK
+19=12531,V,28860,23,DVB-S,QPSK
+20=12571,V,28860,23,DVB-S,QPSK
+21=12611,V,28860,23,DVB-S,QPSK
+22=12651,V,28860,23,DVB-S,QPSK
+23=12691,V,28860,23,DVB-S,QPSK
+24=12731,V,28860,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini
new file mode 100644
index 000000000..aafe00455
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1105.ini
@@ -0,0 +1,14 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1105
+2=ChinaSat 10 (110.5E)
+
+[DVB]
+0=5
+1=3650,V,6200,56,S2,8PSK
+2=3660,V,6200,56,S2,8PSK
+3=3728,V,4340,34,DVB-S,QPSK
+4=3984,V,3617,34,DVB-S,QPSK
+5=4134,V,4340,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini
new file mode 100644
index 000000000..d9c69d3f7
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1130.ini
@@ -0,0 +1,81 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1130
+2=Koreasat 5/Palapa D (113.0E)
+
+[DVB]
+0=72
+1=3420,H,5000,Auto,S2,QPSK
+2=3433,H,4383,56,DVB-S,8PSK
+3=3437,H,1800,34,S2,8PSK
+4=3460,H,29900,34,S2,QPSK
+5=3574,V,6363,78,DVB-S,QPSK
+6=3600,V,31000,23,S2,8PSK
+7=3628,H,17985,23,DVB-S,QPSK
+8=3709,H,10000,35,S2,QPSK
+9=3720,H,30000,34,S2,QPSK
+10=3744,H,3125,78,DVB-S,QPSK
+11=3747,H,6250,34,DVB-S,QPSK
+12=3756,H,6250,34,S2,8PSK
+13=3762,H,3500,34,DVB-S,QPSK
+14=3767,H,4000,45,S2,QPSK
+15=3770,V,3000,34,DVB-S,QPSK
+16=3774,H,6520,34,DVB-S,QPSK
+17=3780,V,29900,34,S2,8PSK
+18=3786,H,5632,34,DVB-S,QPSK
+19=3792,H,3000,34,DVB-S,8PSK
+20=3818,V,27500,34,S2,8PSK
+21=3832,H,12592,34,DVB-S,QPSK
+22=3852,V,2000,56,DVB-S,QPSK
+23=3863,V,4333,34,DVB-S,QPSK
+24=3880,H,30000,34,S2,QPSK
+25=3917,H,3000,34,DVB-S,QPSK
+26=3925,H,2590,34,DVB-S,QPSK
+27=3932,V,15800,56,DVB-S,QPSK
+28=3934,H,6500,34,DVB-S,QPSK
+29=3946,V,7400,56,DVB-S,QPSK
+30=3952,V,3000,34,DVB-S,QPSK
+31=3957,V,3000,34,DVB-S,QPSK
+32=3960,H,30000,34,S2,8PSK
+33=3980,V,31000,23,S2,8PSK
+34=3984,H,2244,34,S2,8PSK
+35=3987,H,2250,34,DVB-S,QPSK
+36=3992,H,2250,34,DVB-S,QPSK
+37=4006,V,6400,34,DVB-S,QPSK
+38=4016,V,3000,34,S2,8PSK
+39=4025,H,2124,34,DVB-S,QPSK
+40=4035,V,6000,34,DVB-S,QPSK
+41=4044,H,2124,34,DVB-S,QPSK
+42=4044,V,2833,34,DVB-S,QPSK
+43=4048,H,2124,34,DVB-S,QPSK
+44=4051,V,1600,56,S2,8PSK
+45=4052,H,3333,78,DVB-S,QPSK
+46=4055,H,3000,34,DVB-S,QPSK
+47=4074,V,3000,34,DVB-S,QPSK
+48=4080,H,28125,34,DVB-S,QPSK
+49=4100,V,30000,34,S2,8PSK
+50=4110,H,11669,34,S2,8PSK
+51=4124,H,5632,34,DVB-S,QPSK
+52=4136,H,3000,34,DVB-S,QPSK
+53=4140,V,30000,78,DVB-S,QPSK
+54=4165,H,20000,34,DVB-S,QPSK
+55=4171,V,15000,Auto,S2,QPSK
+56=4184,V,6700,34,DVB-S,QPSK
+57=12347,H,3180,23,S2,8PSK
+58=12390,V,25600,56,DVB-S,QPSK
+59=12430,V,25600,56,DVB-S,QPSK
+60=12436,H,3564,56,DVB-S,QPSK
+61=12452,H,2500,56,S2,8PSK
+62=12470,V,25600,56,DVB-S,QPSK
+63=12530,H,26000,56,DVB-S,QPSK
+64=12560,H,2300,23,S2,8PSK
+65=12590,H,29900,34,S2,8PSK
+66=12590,V,28000,34,DVB-S,QPSK
+67=12618,V,3900,12,DVB-S,QPSK
+68=12645,V,2893,34,DVB-S,QPSK
+69=12665,H,4320,34,S2,8PSK
+70=12670,V,28000,34,DVB-S,QPSK
+71=12673,H,30000,34,S2,8PSK
+72=12710,H,29900,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini
new file mode 100644
index 000000000..4bfa66270
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1155.ini
@@ -0,0 +1,53 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1155
+2=ChinaSat 6B (115.5E)
+
+[DVB]
+0=44
+1=3600,V,27500,78,DVB-S,QPSK
+2=3640,V,27500,78,DVB-S,QPSK
+3=3680,V,27500,78,DVB-S,QPSK
+4=3709,H,10920,34,DVB-S,QPSK
+5=3740,V,27500,34,DVB-S,QPSK
+6=3750,H,10490,34,DVB-S,QPSK
+7=3769,H,13400,78,DVB-S,QPSK
+8=3780,V,27500,34,DVB-S,QPSK
+9=3796,H,6930,12,DVB-S,QPSK
+10=3807,V,6000,34,DVB-S,QPSK
+11=3808,H,8800,34,DVB-S,QPSK
+12=3815,V,4420,34,DVB-S,QPSK
+13=3825,V,6780,34,DVB-S,QPSK
+14=3834,V,5400,34,DVB-S,QPSK
+15=3840,H,27500,34,DVB-S,QPSK
+16=3846,V,5950,34,DVB-S,QPSK
+17=3854,V,4420,34,DVB-S,QPSK
+18=3861,V,4800,34,DVB-S,QPSK
+19=3871,V,9080,34,DVB-S,QPSK
+20=3880,H,27500,34,DVB-S,QPSK
+21=3885,V,4340,34,DVB-S,QPSK
+22=3892,V,4420,34,DVB-S,QPSK
+23=3903,V,9300,34,DVB-S,QPSK
+24=3913,V,6400,34,DVB-S,QPSK
+25=3920,H,27500,34,DVB-S,QPSK
+26=3929,V,8840,34,DVB-S,QPSK
+27=3940,V,5948,34,DVB-S,QPSK
+28=3950,H,11406,56,DVB-S,QPSK
+29=3951,V,9520,34,DVB-S,QPSK
+30=3960,H,3570,34,DVB-S,QPSK
+31=3971,H,10000,34,DVB-S,QPSK
+32=3980,V,27500,34,DVB-S,QPSK
+33=4000,H,27500,34,DVB-S,QPSK
+34=4020,V,27500,34,DVB-S,QPSK
+35=4040,H,27500,34,DVB-S,QPSK
+36=4060,V,27500,34,DVB-S,QPSK
+37=4080,H,27500,34,DVB-S,QPSK
+38=4116,H,21374,34,DVB-S,QPSK
+39=4140,V,27500,34,DVB-S,QPSK
+40=4147,H,6150,34,DVB-S,QPSK
+41=4158,H,8680,34,DVB-S,QPSK
+42=4171,H,9200,34,DVB-S,QPSK
+43=4175,V,18000,12,DVB-S,QPSK
+44=4192,V,6000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini
new file mode 100644
index 000000000..3ef951d9a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1160.ini
@@ -0,0 +1,42 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1160
+2=ABS 7/Koreasat 6 (116.0E)
+
+[DVB]
+0=33
+1=11747,H,21300,56,S2,8PSK
+2=11785,H,21300,78,DVB-S,QPSK
+3=11823,H,21300,56,S2,8PSK
+4=11862,H,21300,56,S2,8PSK
+5=11900,H,21300,23,S2,8PSK
+6=11938,H,21300,56,S2,8PSK
+7=12290,H,27489,34,S2,8PSK
+8=12330,H,27489,34,S2,8PSK
+9=12350,V,26700,78,DVB-S,QPSK
+10=12370,H,27489,34,S2,8PSK
+11=12390,V,26700,78,DVB-S,QPSK
+12=12410,H,29500,34,S2,8PSK
+13=12430,V,26700,78,DVB-S,QPSK
+14=12450,H,27489,34,S2,8PSK
+15=12467,V,12300,34,S2,QPSK
+16=12490,H,27489,34,S2,8PSK
+17=12497,V,4331,34,S2,8PSK
+18=12501,V,3515,34,DVB-S,QPSK
+19=12506,V,3515,34,DVB-S,QPSK
+20=12511,V,3515,34,DVB-S,QPSK
+21=12517,V,3515,34,DVB-S,QPSK
+22=12523,V,7900,56,S2,8PSK
+23=12530,H,27489,34,S2,8PSK
+24=12570,H,27489,34,S2,8PSK
+25=12610,H,27489,34,S2,8PSK
+26=12650,H,27489,34,S2,8PSK
+27=12670,V,26700,78,DVB-S,QPSK
+28=12687,H,2050,34,DVB-S,QPSK
+29=12690,H,27489,34,S2,8PSK
+30=12695,V,3515,34,DVB-S,QPSK
+31=12706,V,6000,34,DVB-S,QPSK
+32=12724,V,5330,34,S2,8PSK
+33=12730,H,27489,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini
new file mode 100644
index 000000000..d41e3f5ad
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1180.ini
@@ -0,0 +1,11 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1180
+2=Telkom 2 (118.0E)
+
+[DVB]
+0=2
+1=3776,H,2132,34,DVB-S,QPSK
+2=4110,H,2900,12,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini
new file mode 100644
index 000000000..42af4d1c9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1195.ini
@@ -0,0 +1,14 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1195
+2=Thaicom 4 (119.5E)
+
+[DVB]
+0=5
+1=11542,V,15533,Auto,S2,QPSK
+2=11592,V,25000,12,S2,QPSK
+3=11675,V,45000,23,S2,8PSK
+4=12696,V,30000,23,S2,QPSK
+5=12732,V,30000,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini
new file mode 100644
index 000000000..4d833f21b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1222.ini
@@ -0,0 +1,29 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1222
+2=AsiaSat 4 (122.2E)
+
+[DVB]
+0=20
+1=3756,H,21600,23,S2,8PSK
+2=3827,H,6620,34,DVB-S,QPSK
+3=3845,H,6620,34,DVB-S,QPSK
+4=3900,V,26660,23,DVB-S,QPSK
+5=4040,H,4000,34,DVB-S,QPSK
+6=4157,H,2170,34,DVB-S,QPSK
+7=4160,H,2300,34,S2,8PSK
+8=4164,H,5037,78,DVB-S,QPSK
+9=11727,V,25000,23,S2,8PSK
+10=11766,V,27500,23,S2,8PSK
+11=11804,V,27500,23,S2,8PSK
+12=11881,V,275000,23,S2,8PSK
+13=11958,V,27500,23,S2,8PSK
+14=12034,V,27500,23,S2,8PSK
+15=12274,V,6000,34,DVB-S,QPSK
+16=12414,V,43200,23,S2,QPSK
+17=12536,V,4800,56,S2,8PSK
+18=12545,V,2400,34,S2,8PSK
+19=12590,V,6620,34,DVB-S,QPSK
+20=12743,H,10000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini
new file mode 100644
index 000000000..ed948c78e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1240.ini
@@ -0,0 +1,43 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1240
+2=JCSAT 4B (124.0E)
+
+[DVB]
+0=34
+1=12268,V,23303,35,S2,8PSK
+2=12313,H,23303,35,S2,8PSK
+3=12330,H,30000,56,S2,8PSK
+4=12343,H,23303,35,S2,8PSK
+5=12358,V,23303,35,S2,8PSK
+6=12370,H,30000,56,S2,8PSK
+7=12373,H,23303,35,S2,8PSK
+8=12388,V,23303,35,S2,8PSK
+9=12410,H,30000,56,S2,8PSK
+10=12418,V,23303,35,S2,8PSK
+11=12432,H,23303,35,S2,8PSK
+12=12448,V,21096,34,DVB-S,QPSK
+13=12450,H,30000,56,S2,8PSK
+14=12490,H,30000,56,S2,8PSK
+15=12493,H,23303,35,S2,8PSK
+16=12508,V,23303,35,S2,8PSK
+17=12530,H,30000,56,S2,8PSK
+18=12538,V,23303,35,S2,8PSK
+19=12553,H,23303,35,S2,8PSK
+20=12568,V,23303,35,S2,8PSK
+21=12570,H,30000,56,S2,8PSK
+22=12583,H,23303,35,S2,8PSK
+23=12598,V,23303,35,S2,8PSK
+24=12610,H,30000,56,S2,8PSK
+25=12613,H,23303,35,S2,8PSK
+26=12628,V,23303,35,S2,8PSK
+27=12643,H,23303,35,S2,8PSK
+28=12650,H,30000,56,S2,8PSK
+29=12673,H,23303,35,S2,8PSK
+30=12688,V,23303,35,S2,8PSK
+31=12690,H,30000,56,S2,8PSK
+32=12703,H,23303,35,S2,8PSK
+33=12718,V,23303,35,S2,8PSK
+34=12730,H,30000,56,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini
new file mode 100644
index 000000000..738a7debe
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1250.ini
@@ -0,0 +1,38 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1250
+2=ChinaSat 6A (125.0E)
+
+[DVB]
+0=29
+1=3720,H,27500,34,DVB-S,QPSK
+2=3740,V,27500,34,DVB-S,QPSK
+3=3750,H,14900,34,DVB-S,QPSK
+4=3780,V,27500,34,DVB-S,QPSK
+5=3800,H,30600,34,DVB-S,QPSK
+6=3820,V,30000,34,DVB-S,QPSK
+7=3827,H,6220,34,DVB-S,QPSK
+8=3845,H,17778,34,DVB-S,QPSK
+9=3857,V,25000,34,DVB-S,QPSK
+10=3885,H,5720,34,DVB-S,QPSK
+11=3889,V,9988,34,DVB-S,QPSK
+12=3893,H,6880,34,DVB-S,QPSK
+13=3909,H,8934,34,DVB-S,QPSK
+14=3912,V,9900,34,DVB-S,QPSK
+15=3922,H,7250,34,DVB-S,QPSK
+16=3933,H,6590,34,DVB-S,QPSK
+17=3951,H,13400,78,DVB-S,QPSK
+18=3970,H,11580,34,DVB-S,QPSK
+19=3970,V,13400,78,DVB-S,QPSK
+20=3989,H,9070,34,DVB-S,QPSK
+21=3999,H,4420,34,DVB-S,QPSK
+22=4006,H,4420,34,DVB-S,QPSK
+23=4013,H,3950,34,DVB-S,QPSK
+24=4013,V,16600,78,DVB-S,QPSK
+25=4033,V,9580,78,DVB-S,QPSK
+26=4040,H,30600,34,DVB-S,QPSK
+27=4080,H,27500,34,DVB-S,QPSK
+28=4100,V,27500,34,DVB-S,QPSK
+29=4120,H,27500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini
new file mode 100644
index 000000000..bb2f556c0
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1280.ini
@@ -0,0 +1,24 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1280
+2=JCSAT 3A (128.0E)
+
+[DVB]
+0=15
+1=4120,V,30000,34,S2,8PSK
+2=4160,V,30000,34,S2,8PSK
+3=12348,V,23303,35,S2,8PSK
+4=12428,V,23303,35,S2,8PSK
+5=12468,V,23303,35,S2,8PSK
+6=12523,H,23303,35,S2,8PSK
+7=12553,H,23303,35,S2,8PSK
+8=12583,H,23303,35,S2,8PSK
+9=12598,V,23303,35,S2,8PSK
+10=12613,H,23303,35,S2,8PSK
+11=12628,V,21096,34,DVB-S,QPSK
+12=12643,H,23303,35,S2,8PSK
+13=12673,H,23303,35,S2,8PSK
+14=12703,H,23303,35,S2,8PSK
+15=12733,H,23303,35,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini
new file mode 100644
index 000000000..4694425d3
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1320.ini
@@ -0,0 +1,51 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1320
+2=JCSAT 5A/Vinasat 1/2 (132.0E)
+
+[DVB]
+0=42
+1=3413,V,10800,23,S2,8PSK
+2=3433,V,13600,34,S2,8PSK
+3=3446,V,1666,34,S2,8PSK
+4=3451,V,1668,23,S2,8PSK
+5=3480,V,3000,34,S2,8PSK
+6=3493,H,1600,34,DVB-S,QPSK
+7=3544,V,1600,34,S2,8PSK
+8=3549,V,1200,34,S2,8PSK
+9=3560,V,1510,34,DVB-S,QPSK
+10=3572,V,8000,23,S2,8PSK
+11=3590,V,19200,23,S2,8PSK
+12=10968,H,28800,34,S2,8PSK
+13=11008,H,28800,34,S2,8PSK
+14=11048,H,28800,56,DVB-S,QPSK
+15=11050,V,30000,34,S2,8PSK
+16=11085,H,24000,34,S2,8PSK
+17=11088,V,28800,34,S2,8PSK
+18=11119,V,14400,34,S2,8PSK
+19=11135,H,9600,34,S2,8PSK
+20=11167,V,30000,34,S2,8PSK
+21=11472,H,23200,34,S2,8PSK
+22=11510,V,30000,34,S2,8PSK
+23=11517,H,4702,34,DVB-S,QPSK
+24=11523,H,4702,34,DVB-S,QPSK
+25=11531,H,2500,34,DVB-S,QPSK
+26=11549,H,28500,56,DVB-S,QPSK
+27=11550,V,30000,34,S2,8PSK
+28=11589,H,28800,34,DVB-S,QPSK
+29=11590,V,30000,34,S2,8PSK
+30=11629,H,28800,34,DVB-S,QPSK
+31=11630,V,30000,34,S2,8PSK
+32=11669,H,30000,34,S2,8PSK
+33=11670,V,30000,34,S2,8PSK
+34=12257,V,3096,34,DVB-S,QPSK
+35=12288,H,7241,34,DVB-S,QPSK
+36=12320,V,7241,34,DVB-S,QPSK
+37=12340,H,7241,34,DVB-S,QPSK
+38=12400,V,7241,34,DVB-S,QPSK
+39=12408,H,7241,34,DVB-S,QPSK
+40=12420,H,7241,34,DVB-S,QPSK
+41=12711,V,19476,12,S2,8PSK
+42=12746,H,3096,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini
new file mode 100644
index 000000000..4ca7c83a0
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1340.ini
@@ -0,0 +1,27 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1340
+2=Apstar 6 (134.0E)
+
+[DVB]
+0=18
+1=3720,H,30000,Auto,S2,QPSK
+2=3776,H,5632,34,DVB-S,QPSK
+3=3830,V,3700,34,S2,8PSK
+4=3840,H,27500,34,DVB-S,QPSK
+5=3878,H,3000,34,DVB-S,QPSK
+6=3913,V,1920,45,S2,QPSK
+7=4020,V,30000,34,S2,8PSK
+8=4032,H,2688,34,S2,8PSK
+9=4051,H,9628,34,DVB-S,QPSK
+10=4149,H,13500,34,DVB-S,QPSK
+11=4160,H,2963,34,DVB-S,QPSK
+12=12269,V,18000,12,DVB-S,QPSK
+13=12322,V,3600,34,DVB-S,QPSK
+14=12395,V,27500,34,DVB-S,QPSK
+15=12435,V,27500,34,DVB-S,QPSK
+16=12515,V,27500,34,DVB-S,QPSK
+17=12595,V,27500,34,DVB-S,QPSK
+18=12675,V,27500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini
new file mode 100644
index 000000000..cb952425b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1380.ini
@@ -0,0 +1,37 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1380
+2=Telstar 18 (138.0E)
+
+[DVB]
+0=28
+1=3703,V,4444,23,S2,8PSK
+2=3707,H,4500,34,S2,8PSK
+3=3734,H,2222,34,S2,8PSK
+4=3820,V,30000,34,S2,8PSK
+5=3837,H,2200,34,DVB-S,QPSK
+6=3847,H,4444,34,S2,8PSK
+7=3854,H,6700,34,DVB-S,QPSK
+8=3866,H,4290,34,DVB-S,QPSK
+9=3872,H,6660,34,DVB-S,QPSK
+10=3933,V,3000,34,DVB-S,QPSK
+11=3948,V,17600,34,S2,8PSK
+12=12272,H,33333,23,S2,8PSK
+13=12292,V,45000,Auto,S2,8PSK
+14=12354,V,43000,34,DVB-S,QPSK
+15=12401,V,22425,34,DVB-S,QPSK
+16=12429,H,3330,12,DVB-S,QPSK
+17=12430,V,22425,56,S2,8PSK
+18=12439,H,2500,34,DVB-S,QPSK
+19=12443,H,1495,34,DVB-S,QPSK
+20=12472,V,33500,34,S2,8PSK
+21=12499,V,7200,34,S2,8PSK
+22=12507,H,45000,23,S2,8PSK
+23=12538,V,41250,12,DVB-S,QPSK
+24=12598,V,43000,34,S2,8PSK
+25=12629,H,43200,34,S2,8PSK
+26=12660,V,45000,56,DVB-S,QPSK
+27=12690,H,43200,34,S2,8PSK
+28=12721,V,41250,12,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini
new file mode 100644
index 000000000..b4e6dc7c0
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1400.ini
@@ -0,0 +1,31 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1400
+2=Express AM5/AT2 (140.0E)
+
+[DVB]
+0=22
+1=3571,V,3000,34,DVB-S,QPSK
+2=3577,V,4285,34,DVB-S,QPSK
+3=3584,V,3000,34,DVB-S,QPSK
+4=3589,V,4340,34,DVB-S,QPSK
+5=3609,V,4340,34,DVB-S,QPSK
+6=3627,V,4340,34,DVB-S,QPSK
+7=3632,V,4340,34,DVB-S,QPSK
+8=3639,V,1000,34,DVB-S,QPSK
+9=3675,V,33483,78,DVB-S,QPSK
+10=3874,V,3200,34,DVB-S,QPSK
+11=4180,V,4340,34,DVB-S,QPSK
+12=10981,V,44948,56,DVB-S,QPSK
+13=11082,H,2500,56,S2,8PSK
+14=11104,V,3617,34,S2,8PSK
+15=11495,V,10600,34,S2,8PSK
+16=11530,H,22250,23,S2,8PSK
+17=11557,H,22250,23,S2,8PSK
+18=11657,V,24800,56,DVB-S,QPSK
+19=11681,V,15520,23,S2,8PSK
+20=12188,H,27500,34,DVB-S,QPSK
+21=12207,V,27500,34,S2,8PSK
+22=12341,H,27500,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini
new file mode 100644
index 000000000..e31e028ab
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1440.ini
@@ -0,0 +1,22 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1440
+2=Superbird C2 (144.0E)
+
+[DVB]
+0=13
+1=12276,V,7457,23,S2,8PSK
+2=12306,V,7457,23,S2,8PSK
+3=12319,V,14910,34,DVB-S,QPSK
+4=12336,V,7457,23,S2,QPSK
+5=12385,V,7457,23,S2,8PSK
+6=12394,V,7457,23,S2,QPSK
+7=12403,V,7457,23,S2,8PSK
+8=12508,V,21096,34,DVB-S,QPSK
+9=12546,H,9365,35,S2,8PSK
+10=12549,V,2900,34,DVB-S,QPSK
+11=12558,V,3515,34,DVB-S,QPSK
+12=12598,V,21096,34,DVB-S,QPSK
+13=12658,V,21096,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini
new file mode 100644
index 000000000..6acfb1679
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1500.ini
@@ -0,0 +1,12 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1500
+2=JCSAT 1B (150.0E)
+
+[DVB]
+0=3
+1=12423,V,6912,12,DVB-S,QPSK
+2=12662,V,12825,34,DVB-S,QPSK
+3=12693,V,12825,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini
new file mode 100644
index 000000000..0034b3e13
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1520.ini
@@ -0,0 +1,25 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1520
+2=Optus D2 (152.0E)
+
+[DVB]
+0=16
+1=12274,V,6670,34,DVB-S,QPSK
+2=12295,V,1644,Auto,DVB-S,QPSK
+3=12328,V,15000,78,DVB-S,QPSK
+4=12469,H,6670,Auto,DVB-S,QPSK
+5=12519,V,22500,34,DVB-S,QPSK
+6=12536,H,6980,34,DVB-S,QPSK
+7=12545,H,6980,34,DVB-S,QPSK
+8=12546,V,22500,34,DVB-S,QPSK
+9=12554,H,6980,34,DVB-S,QPSK
+10=12581,H,22500,34,DVB-S,QPSK
+11=12608,H,22500,34,DVB-S,QPSK
+12=12639,V,15000,78,DVB-S,QPSK
+13=12657,V,15000,78,DVB-S,QPSK
+14=12675,V,15000,78,DVB-S,QPSK
+15=12706,V,22500,34,DVB-S,QPSK
+16=12734,V,22500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini
new file mode 100644
index 000000000..365575a8c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1540.ini
@@ -0,0 +1,32 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1540
+2=JCSAT 2A (154.0E)
+
+[DVB]
+0=23
+1=3936,V,3333,34,DVB-S,QPSK
+2=12263,V,5082,34,DVB-S,QPSK
+3=12278,V,4820,34,DVB-S,QPSK
+4=12280,H,4820,34,DVB-S,QPSK
+5=12298,V,21096,34,DVB-S,QPSK
+6=12310,H,3515,34,S2,8PSK
+7=12317,H,6036,35,S2,QPSK
+8=12318,V,4820,34,DVB-S,QPSK
+9=12324,V,4820,34,DVB-S,QPSK
+10=12331,V,4820,34,DVB-S,QPSK
+11=12338,V,4820,34,DVB-S,QPSK
+12=12362,V,4820,34,DVB-S,QPSK
+13=12373,H,7082,34,S2,8PSK
+14=12376,V,1680,34,S2,QPSK
+15=12409,V,4820,34,DVB-S,QPSK
+16=12436,H,3100,34,DVB-S,QPSK
+17=12505,H,2856,23,S2,8PSK
+18=12505,V,4821,34,DVB-S,QPSK
+19=12576,V,7242,34,DVB-S,QPSK
+20=12613,H,21096,34,DVB-S,QPSK
+21=12688,V,21096,34,DVB-S,QPSK
+22=12700,H,5274,34,DVB-S,QPSK
+23=12729,V,3096,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini
new file mode 100644
index 000000000..be5b9c2f6
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1560.ini
@@ -0,0 +1,44 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1560
+2=Optus C1/D3 (156.0E)
+
+[DVB]
+0=35
+1=11720,H,29455,35,S2,8PSK
+2=11762,H,27800,34,DVB-S,QPSK
+3=11804,V,30000,35,S2,8PSK
+4=11845,V,27800,Auto,DVB-S,QPSK
+5=11886,V,30000,35,S2,8PSK
+6=11886,H,27800,34,DVB-S,QPSK
+7=11928,V,30000,35,S2,8PSK
+8=11928,H,27800,34,DVB-S,QPSK
+9=11970,H,27800,34,DVB-S,QPSK
+10=12011,V,27800,34,DVB-S,QPSK
+11=12011,H,29455,35,S2,8PSK
+12=12052,V,27800,34,DVB-S,QPSK
+13=12052,H,29455,35,S2,8PSK
+14=12094,V,27800,34,DVB-S,QPSK
+15=12094,H,29455,35,S2,8PSK
+16=12136,V,27800,34,DVB-S,QPSK
+17=12136,H,27800,34,DVB-S,QPSK
+18=12177,V,27800,34,DVB-S,QPSK
+19=12177,H,27800,34,DVB-S,QPSK
+20=12358,H,27800,34,DVB-S,QPSK
+21=12369,V,30000,35,S2,8PSK
+22=12398,H,27800,34,DVB-S,QPSK
+23=12407,V,24450,Auto,DVB-S,QPSK
+24=12438,H,27800,34,DVB-S,QPSK
+25=12478,H,27800,34,DVB-S,QPSK
+26=12487,V,30000,35,S2,8PSK
+27=12518,H,27800,34,DVB-S,QPSK
+28=12558,H,27800,34,DVB-S,QPSK
+29=12567,V,30000,35,S2,8PSK
+30=12598,H,27800,34,DVB-S,QPSK
+31=12607,V,30000,35,S2,8PSK
+32=12638,H,27800,34,DVB-S,QPSK
+33=12647,V,30000,35,S2,8PSK
+34=12689,H,27800,34,DVB-S,QPSK
+35=12707,H,22500,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini
new file mode 100644
index 000000000..567b3cc09
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1590.ini
@@ -0,0 +1,14 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1590
+2=ABS 6 (159.0E)
+
+[DVB]
+0=5
+1=3888,V,8340,23,DVB-S,QPSK
+2=3897,V,4445,34,DVB-S,QPSK
+3=3908,V,4445,34,DVB-S,QPSK
+4=3915,V,4445,34,DVB-S,QPSK
+5=12696,V,10000,12,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini
new file mode 100644
index 000000000..865061739
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600 OPTUS D1 FTA (160.0E).ini
@@ -0,0 +1,11 @@
+[SATTYPE]
+1=1600.0
+2=OPTUS D1 FTA (160.0E)
+
+[DVB]
+0=5
+1=12456,H,22500,0
+2=12483,H,22500,0
+3=12644,H,22500,0
+4=12707,H,22500,0
+5=12381,V,3750,23,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini
new file mode 100644
index 000000000..08083f62f
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1600.ini
@@ -0,0 +1,47 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1600
+2=Optus D1 (160.0E)
+
+[DVB]
+0=38
+1=12267,H,22500,23,S2,8PSK
+2=12295,H,22500,34,S2,8PSK
+3=12331,H,22500,23,S2,8PSK
+4=12348,H,14293,78,DVB-S,QPSK
+5=12358,H,22500,23,S2,8PSK
+6=12381,V,3750,23,S2,QPSK
+7=12394,H,22500,34,DVB-S,QPSK
+8=12421,H,22500,34,DVB-S,QPSK
+9=12430,V,6111,Auto,DVB-S,QPSK
+10=12452,H,12600,56,DVB-S,QPSK
+11=12456,H,22500,34,DVB-S,QPSK
+12=12470,H,12600,56,DVB-S,QPSK
+13=12483,H,22500,34,DVB-S,QPSK
+14=12487,H,12600,56,DVB-S,QPSK
+15=12514,H,14294,78,DVB-S,QPSK
+16=12519,H,22500,34,DVB-S,QPSK
+17=12528,V,6660,Auto,DVB-S,QPSK
+18=12532,H,14294,78,DVB-S,QPSK
+19=12546,V,6670,Auto,DVB-S,QPSK
+20=12546,H,22500,34,DVB-S,QPSK
+21=12550,H,14294,78,DVB-S,QPSK
+22=12556,V,6670,Auto,DVB-S,QPSK
+23=12577,H,14294,78,DVB-S,QPSK
+24=12581,H,22500,34,DVB-S,QPSK
+25=12595,H,14294,78,DVB-S,QPSK
+26=12607,V,7177,Auto,DVB-S,QPSK
+27=12608,H,22500,34,DVB-S,QPSK
+28=12613,H,14294,78,DVB-S,QPSK
+29=12637,V,5100,Auto,DVB-S,QPSK
+30=12644,H,22500,34,DVB-S,QPSK
+31=12661,V,7200,Auto,DVB-S,QPSK
+32=12670,V,7200,Auto,DVB-S,QPSK
+33=12671,H,22500,34,DVB-S,QPSK
+34=12679,V,7200,Auto,DVB-S,QPSK
+35=12681,H,7200,34,DVB-S,QPSK
+36=12699,H,7200,34,DVB-S,QPSK
+37=12707,H,22500,34,DVB-S,QPSK
+38=12734,H,22500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini
new file mode 100644
index 000000000..9a16504dc
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1620.ini
@@ -0,0 +1,32 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1620
+2=Superbird B2 (162.0E)
+
+[DVB]
+0=23
+1=12277,V,6150,34,DVB-S,QPSK
+2=12286,V,6150,34,DVB-S,QPSK
+3=12295,V,6150,34,DVB-S,QPSK
+4=12304,V,6150,34,DVB-S,QPSK
+5=12373,V,4095,34,DVB-S,QPSK
+6=12382,H,14143,56,S2,QPSK
+7=12384,V,4095,34,DVB-S,QPSK
+8=12423,V,6143,35,S2,8PSK
+9=12440,V,11708,34,S2,QPSK
+10=12455,H,4095,34,DVB-S,QPSK
+11=12500,H,10000,23,DVB-S,QPSK
+12=12523,V,6428,34,DVB-S,QPSK
+13=12526,H,5274,34,DVB-S,QPSK
+14=12535,H,5274,34,DVB-S,QPSK
+15=12543,H,5274,34,DVB-S,QPSK
+16=12550,H,5274,34,DVB-S,QPSK
+17=12557,V,5275,34,DVB-S,QPSK
+18=12596,V,6620,34,DVB-S,QPSK
+19=12644,H,5275,34,DVB-S,QPSK
+20=12656,V,5275,34,DVB-S,QPSK
+21=12664,V,5275,34,DVB-S,QPSK
+22=12676,H,6144,34,DVB-S,QPSK
+23=12724,H,7072,34,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini
new file mode 100644
index 000000000..9650ab47a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1640.ini
@@ -0,0 +1,12 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1640
+2=Optus 10/B3 (164.0E)
+
+[DVB]
+0=3
+1=12345,V,7200,Auto,DVB-S,QPSK
+2=12388,H,7200,Auto,DVB-S,QPSK
+3=12463,V,7200,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini
new file mode 100644
index 000000000..8c040e884
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1660.ini
@@ -0,0 +1,52 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1660
+2=Intelsat 19 (166.0E)
+
+[DVB]
+0=43
+1=3705,V,3000,78,DVB-S,QPSK
+2=3719,V,1620,56,S2,8PSK
+3=3724,V,5185,34,DVB-S,QPSK
+4=3736,V,2963,34,DVB-S,QPSK
+5=3740,H,27500,34,DVB-S,QPSK
+6=3760,V,27690,34,DVB-S,QPSK
+7=3780,H,25000,34,DVB-S,QPSK
+8=3784,V,1464,35,S2,8PSK
+9=3795,V,3500,34,DVB-S,QPSK
+10=3800,V,3500,34,DVB-S,QPSK
+11=3805,V,3960,34,S2,QPSK
+12=3810,H,15000,Auto,S2,8PSK
+13=3815,V,4400,34,DVB-S,QPSK
+14=3851,V,9950,34,DVB-S,QPSK
+15=3900,H,30000,23,S2,8PSK
+16=3920,V,28800,12,S2,QPSK
+17=3940,H,27690,78,DVB-S,QPSK
+18=3959,V,7090,34,DVB-S,QPSK
+19=3980,H,27690,34,DVB-S,QPSK
+20=4040,V,30000,34,S2,8PSK
+21=4060,H,26590,12,DVB-S,QPSK
+22=4080,V,28270,23,S2,8PSK
+23=4086,H,5787,34,DVB-S,QPSK
+24=4096,H,5787,34,DVB-S,QPSK
+25=4146,V,5632,34,DVB-S,QPSK
+26=4165,V,3448,35,S2,QPSK
+27=4180,H,30000,23,S2,8PSK
+28=12286,H,30000,34,S2,QPSK
+29=12390,H,7200,23,S2,8PSK
+30=12399,H,7200,23,S2,8PSK
+31=12407,H,29500,34,S2,8PSK
+32=12412,V,14400,Auto,S2,8PSK
+33=12432,H,5632,Auto,DVB-S,QPSK
+34=12480,V,6666,Auto,DVB-S,QPSK
+35=12495,H,15000,23,S2,8PSK
+36=12526,H,30000,34,S2,8PSK
+37=12557,H,15000,34,S2,8PSK
+38=12575,H,13845,23,DVB-S,QPSK
+39=12592,H,2894,34,DVB-S,QPSK
+40=12613,H,2222,12,DVB-S,QPSK
+41=12646,H,28066,34,DVB-S,QPSK
+42=12686,H,28124,34,DVB-S,QPSK
+43=12726,H,28066,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini
new file mode 100644
index 000000000..c7470a5e4
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1690.ini
@@ -0,0 +1,14 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1690
+2=Intelsat 8 (169.0E)
+
+[DVB]
+0=5
+1=3771,H,13234,Auto,S2,QPSK
+2=3809,V,4286,34,DVB-S,QPSK
+3=3815,V,4286,34,DVB-S,QPSK
+4=3816,H,6620,34,DVB-S,QPSK
+5=4032,H,8545,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini
new file mode 100644
index 000000000..6f0a6f0ea
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1720.ini
@@ -0,0 +1,17 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1720
+2=Eutelsat 172A (172.0E)
+
+[DVB]
+0=8
+1=3916,H,3330,34,DVB-S,QPSK
+2=11515,V,2500,89,S2,QPSK
+3=11537,V,1500,Auto,S2,QPSK
+4=11623,V,3500,89,S2,QPSK
+5=11646,V,2200,Auto,S2,QPSK
+6=12716,V,7200,34,DVB-S,QPSK
+7=12725,V,7200,34,DVB-S,QPSK
+8=12734,V,7200,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini
new file mode 100644
index 000000000..a3f5044cf
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1800.ini
@@ -0,0 +1,19 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1800
+2=Intelsat 18 (180.0E)
+
+[DVB]
+0=10
+1=3753,V,28000,34,DVB-S,QPSK
+2=4015,H,30000,Auto,S2,QPSK
+3=4070,V,3443,34,S2,QPSK
+4=4095,H,30000,Auto,S2,QPSK
+5=4174,H,3680,23,DVB-S,QPSK
+6=10995,H,45000,34,S2,QPSK
+7=11075,V,45000,34,S2,8PSK
+8=11075,H,45000,34,S2,QPSK
+9=11155,V,28588,34,S2,8PSK
+10=11155,H,28588,56,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini
new file mode 100644
index 000000000..8775bb5d3
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/1830.ini
@@ -0,0 +1,18 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=1830
+2=NSS 9/Yamal 300K (177.0W)
+
+[DVB]
+0=9
+1=3792,V,2048,23,S2,QPSK
+2=3922,V,1122,56,S2,QPSK
+3=3976,H,30000,23,DVB-S,QPSK
+4=3987,V,8950,23,DVB-S,QPSK
+5=3999,V,2960,34,DVB-S,QPSK
+6=4055,H,30000,34,DVB-S,QPSK
+7=4103,V,15196,56,S2,QPSK
+8=4152,V,2127,Auto,DVB-S,QPSK
+9=4163,V,2644,34,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini
new file mode 100644
index 000000000..123055dd4
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2210.ini
@@ -0,0 +1,12 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2210
+2=AMC 8 (139.0W)
+
+[DVB]
+0=3
+1=3756,V,2100,34,DVB-S,QPSK
+2=4056,H,13250,34,DVB-S,QPSK
+3=4111,V,5000,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini
new file mode 100644
index 000000000..fe661385b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2230.ini
@@ -0,0 +1,11 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2230
+2=AMC 7 (137.0W)
+
+[DVB]
+0=2
+1=3760,H,25195,34,DVB-S,QPSK
+2=4100,V,6500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini
new file mode 100644
index 000000000..4f5a9494d
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2250.ini
@@ -0,0 +1,25 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2250
+2=AMC 10 (135.0W)
+
+[DVB]
+0=16
+1=3720,V,30000,56,S2,8PSK
+2=3760,V,30000,56,S2,8PSK
+3=3780,H,29200,34,DVB-S,QPSK
+4=3800,V,30000,56,S2,QPSK
+5=3820,H,29270,34,DVB-S,QPSK
+6=3840,V,29270,34,DVB-S,QPSK
+7=3900,H,29270,34,DVB-S,QPSK
+8=3920,V,29270,34,DVB-S,QPSK
+9=3960,V,29270,34,DVB-S,QPSK
+10=3980,H,29270,34,DVB-S,QPSK
+11=4040,V,30000,56,S2,8PSK
+12=4080,V,29270,34,DVB-S,QPSK
+13=4120,V,30000,34,S2,8PSK
+14=4136,H,19510,34,DVB-S,QPSK
+15=4149,H,9760,34,DVB-S,QPSK
+16=4180,H,29270,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini
new file mode 100644
index 000000000..18a777c4b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2270.ini
@@ -0,0 +1,32 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2270
+2=Galaxy 15 (133.0W)
+
+[DVB]
+0=23
+1=3720,H,29270,56,DVB-S,QPSK
+2=3740,V,31250,34,S2,8PSK
+3=3760,H,19510,34,DVB-S,QPSK
+4=3780,V,31250,34,S2,8PSK
+5=3790,H,11936,34,DVB-S,QPSK
+6=3808,H,16303,34,S2,8PSK
+7=3825,V,13800,56,DVB-S,QPSK
+8=3840,H,29270,34,DVB-S,QPSK
+9=3860,V,28000,34,DVB-S,QPSK
+10=3900,V,31250,34,S2,8PSK
+11=3960,H,19510,34,DVB-S,QPSK
+12=3980,V,29270,34,DVB-S,QPSK
+13=4000,H,30000,56,S2,8PSK
+14=4020,V,29270,Auto,DVB-S,QPSK
+15=4025,H,4880,34,DVB-S,QPSK
+16=4044,H,22500,56,S2,8PSK
+17=4060,V,29270,78,DVB-S,QPSK
+18=4080,H,30000,56,S2,8PSK
+19=4100,V,31250,34,S2,8PSK
+20=4120,H,31250,34,S2,8PSK
+21=4140,V,31250,34,S2,8PSK
+22=4160,H,29270,78,DVB-S,QPSK
+23=4180,V,29270,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini
new file mode 100644
index 000000000..631af13d2
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2290.ini
@@ -0,0 +1,32 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2290
+2=AMC 11 (131.0W)
+
+[DVB]
+0=23
+1=3760,V,19510,34,DVB-S,QPSK
+2=3780,H,29270,34,DVB-S,QPSK
+3=3790,V,12400,78,DVB-S,QPSK
+4=3808,V,15800,56,S2,8PSK
+5=3860,H,30000,56,S2,8PSK
+6=3880,V,19510,34,DVB-S,QPSK
+7=3900,H,30000,56,S2,QPSK
+8=3910,V,13200,56,DVB-S,8PSK
+9=3928,V,14323,56,DVB-S,QPSK
+10=3940,H,29270,34,DVB-S,QPSK
+11=3960,V,30000,34,S2,8PSK
+12=3980,H,30000,56,S2,8PSK
+13=3995,V,19510,34,DVB-S,QPSK
+14=4020,H,29270,34,DVB-S,QPSK
+15=4040,V,29270,34,DVB-S,QPSK
+16=4060,H,29270,34,DVB-S,QPSK
+17=4075,V,19510,34,DVB-S,QPSK
+18=4092,V,9760,34,DVB-S,QPSK
+19=4100,H,30000,56,S2,8PSK
+20=4120,V,30000,56,S2,8PSK
+21=4140,H,19510,34,DVB-S,QPSK
+22=4160,V,29200,34,DVB-S,QPSK
+23=4180,H,29270,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini
new file mode 100644
index 000000000..5915c2365
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2310.ini
@@ -0,0 +1,41 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2310
+2=Ciel 2/Galaxy 12 (129.0W)
+
+[DVB]
+0=32
+1=12224,V,21500,23,DVB-S,8PSK
+2=12239,H,21500,23,DVB-S,8PSK
+3=12253,V,21500,23,DVB-S,8PSK
+4=12268,H,21500,23,DVB-S,8PSK
+5=12282,V,21500,23,DVB-S,8PSK
+6=12297,H,21500,23,DVB-S,8PSK
+7=12311,V,21500,23,DVB-S,8PSK
+8=12326,H,21500,23,DVB-S,8PSK
+9=12341,V,21500,23,DVB-S,8PSK
+10=12355,H,21500,23,DVB-S,8PSK
+11=12370,V,21500,23,DVB-S,8PSK
+12=12384,H,21500,23,DVB-S,8PSK
+13=12399,V,20000,78,DVB-S,8PSK
+14=12414,H,21500,23,DVB-S,8PSK
+15=12428,V,21500,23,DVB-S,8PSK
+16=12443,H,21500,23,DVB-S,8PSK
+17=12457,V,21500,23,DVB-S,8PSK
+18=12472,H,21500,23,DVB-S,8PSK
+19=12486,V,21500,23,DVB-S,8PSK
+20=12501,H,21500,23,DVB-S,8PSK
+21=12516,V,20000,56,DVB-S,QPSK
+22=12530,H,21500,23,DVB-S,8PSK
+23=12545,V,21500,23,DVB-S,8PSK
+24=12559,H,21500,23,DVB-S,8PSK
+25=12574,V,21500,23,DVB-S,8PSK
+26=12588,H,21500,23,DVB-S,8PSK
+27=12603,V,21500,23,DVB-S,8PSK
+28=12618,H,21500,23,DVB-S,8PSK
+29=12632,V,21500,23,DVB-S,8PSK
+30=12647,H,21500,23,DVB-S,8PSK
+31=12661,V,21500,23,DVB-S,8PSK
+32=12676,H,21500,23,DVB-S,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini
new file mode 100644
index 000000000..3ab17e6a1
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2330.ini
@@ -0,0 +1,32 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2330
+2=Galaxy 13/Horizons 1 (127.0W)
+
+[DVB]
+0=23
+1=3760,V,28076,34,DVB-S,QPSK
+2=3780,H,30000,23,S2,8PSK
+3=3800,V,27690,34,DVB-S,QPSK
+4=3820,H,30000,56,S2,8PSK
+5=3840,V,30000,56,S2,8PSK
+6=3880,V,30000,89,S2,8PSK
+7=3900,H,29270,78,DVB-S,QPSK
+8=3920,V,29270,78,DVB-S,QPSK
+9=3960,V,30000,56,S2,8PSK
+10=3980,H,30000,34,S2,8PSK
+11=4000,V,30000,89,S2,8PSK
+12=4052,H,17500,56,S2,8PSK
+13=4066,H,3310,34,DVB-S,QPSK
+14=4070,H,3257,34,S2,8PSK
+15=4080,V,28076,34,DVB-S,QPSK
+16=4120,V,30000,56,S2,8PSK
+17=4140,H,30000,34,S2,8PSK
+18=4160,V,30000,56,S2,8PSK
+19=11727,V,6620,Auto,DVB-S,QPSK
+20=12050,H,13020,Auto,DVB-S,QPSK
+21=12087,V,6111,Auto,DVB-S,QPSK
+22=12140,V,30000,34,DVB-S,QPSK
+23=12180,V,16278,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini
new file mode 100644
index 000000000..cdaa5042e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2350.ini
@@ -0,0 +1,43 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2350
+2=AMC 21/Galaxy 14 (125.0W)
+
+[DVB]
+0=34
+1=3720,H,26667,34,DVB-S,QPSK
+2=3740,V,30000,56,S2,8PSK
+3=3760,H,19886,34,DVB-S,QPSK
+4=3780,V,30000,34,S2,8PSK
+5=3820,V,30000,34,S2,8PSK
+6=3840,H,30000,56,S2,8PSK
+7=3860,V,30000,56,S2,8PSK
+8=3880,H,30000,56,S2,8PSK
+9=3900,V,29079,56,S2,8PSK
+10=3920,H,29270,34,DVB-S,QPSK
+11=3940,V,19510,34,DVB-S,QPSK
+12=3960,H,29270,34,DVB-S,QPSK
+13=3980,V,30000,56,S2,8PSK
+14=4020,V,30000,56,S2,8PSK
+15=4040,H,30000,34,S2,8PSK
+16=4080,H,30000,34,S2,8PSK
+17=4100,V,29270,78,DVB-S,QPSK
+18=4120,H,29270,34,DVB-S,QPSK
+19=4140,V,30000,34,S2,8PSK
+20=4160,H,30000,56,S2,8PSK
+21=4180,V,30000,56,S2,8PSK
+22=11740,V,30000,34,S2,QPSK
+23=11760,H,30000,34,S2,QPSK
+24=11780,V,30000,34,S2,QPSK
+25=11800,H,30000,34,S2,QPSK
+26=11980,V,30000,34,S2,QPSK
+27=12106,V,2398,23,S2,QPSK
+28=12112,V,8703,34,S2,8PSK
+29=12146,H,6250,34,S2,QPSK
+30=12155,H,6250,34,S2,QPSK
+31=12163,H,4444,34,DVB-S,QPSK
+32=12169,H,4444,34,DVB-S,QPSK
+33=12175,H,4444,34,DVB-S,QPSK
+34=12180,V,30000,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini
new file mode 100644
index 000000000..ce1a1f239
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2370.ini
@@ -0,0 +1,23 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2370
+2=Galaxy 18 (123.0W)
+
+[DVB]
+0=14
+1=4020,H,30000,56,S2,8PSK
+2=4040,V,29270,34,DVB-S,QPSK
+3=4100,H,29270,34,DVB-S,QPSK
+4=4120,V,29270,34,DVB-S,QPSK
+5=4140,H,30000,56,S2,8PSK
+6=4160,V,29270,34,DVB-S,QPSK
+7=4176,H,20000,34,DVB-S,QPSK
+8=11732,H,13240,34,DVB-S,QPSK
+9=11747,V,2667,Auto,DVB-S,QPSK
+10=11772,V,3361,34,S2,QPSK
+11=11776,V,2848,23,DVB-S,QPSK
+12=11848,V,1784,34,S2,8PSK
+13=12033,H,8200,34,DVB-S,QPSK
+14=12078,V,3680,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini
new file mode 100644
index 000000000..73ca36a7b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2390.ini
@@ -0,0 +1,42 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2390
+2=EchoStar 9/Galaxy 23 (121.0W)
+
+[DVB]
+0=33
+1=3714,H,4340,78,DVB-S,QPSK
+2=3730,H,8824,34,DVB-S,QPSK
+3=3732,V,14400,89,S2,8PSK
+4=3750,V,14027,34,DVB-S,QPSK
+5=3780,V,29270,78,DVB-S,QPSK
+6=3800,H,19510,34,DVB-S,QPSK
+7=3820,V,29270,34,DVB-S,QPSK
+8=3840,H,30000,56,S2,8PSK
+9=3877,H,4444,34,DVB-S,QPSK
+10=3889,H,13020,34,DVB-S,QPSK
+11=3910,H,14400,34,S2,8PSK
+12=3980,V,29270,78,DVB-S,QPSK
+13=4000,H,19510,34,DVB-S,QPSK
+14=4011,V,15000,56,S2,8PSK
+15=4033,V,8333,56,DVB-S,QPSK
+16=4050,V,2590,34,DVB-S,QPSK
+17=4055,V,6510,34,DVB-S,QPSK
+18=4080,H,30000,56,S2,8PSK
+19=4100,V,29270,34,DVB-S,QPSK
+20=4115,H,18085,34,DVB-S,QPSK
+21=4172,V,18916,23,S2,8PSK
+22=4192,V,11070,56,DVB-S,QPSK
+23=11715,V,6510,Auto,DVB-S,QPSK
+24=11724,V,6510,Auto,DVB-S,QPSK
+25=11899,V,20000,34,DVB-S,QPSK
+26=11928,V,20000,34,DVB-S,QPSK
+27=11943,H,20000,34,DVB-S,QPSK
+28=11957,V,20000,12,DVB-S,QPSK
+29=11990,H,20000,34,DVB-S,QPSK
+30=12016,V,20000,34,DVB-S,QPSK
+31=12045,V,20000,34,DVB-S,QPSK
+32=12167,H,6000,Auto,DVB-S,QPSK
+33=12171,V,5800,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini
new file mode 100644
index 000000000..188507e9d
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2410.ini
@@ -0,0 +1,72 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2410
+2=Anik F3/DirecTV 7S/EchoStar 14 (119.0W)
+
+[DVB]
+0=63
+1=3934,H,5714,34,DVB-S,QPSK
+2=11715,V,20000,34,DVB-S,QPSK
+3=11728,H,20000,34,DVB-S,QPSK
+4=11745,V,20000,34,DVB-S,QPSK
+5=11758,H,20000,34,DVB-S,QPSK
+6=11776,V,20000,34,DVB-S,QPSK
+7=11789,H,20000,34,DVB-S,QPSK
+8=11806,V,20000,34,DVB-S,QPSK
+9=11819,H,20000,34,DVB-S,QPSK
+10=11837,V,20000,34,DVB-S,QPSK
+11=11850,H,20000,34,DVB-S,QPSK
+12=11867,V,20000,34,DVB-S,QPSK
+13=11880,H,20000,34,DVB-S,QPSK
+14=11898,V,20000,34,DVB-S,QPSK
+15=11911,H,20000,34,DVB-S,QPSK
+16=11928,V,20000,34,DVB-S,QPSK
+17=11972,H,20000,34,DVB-S,QPSK
+18=11989,V,20000,34,DVB-S,QPSK
+19=12002,H,20000,34,DVB-S,QPSK
+20=12020,V,20000,34,DVB-S,QPSK
+21=12033,H,20000,34,DVB-S,QPSK
+22=12050,V,20000,34,DVB-S,QPSK
+23=12063,H,20000,34,DVB-S,QPSK
+24=12081,V,20000,34,DVB-S,QPSK
+25=12094,H,20000,34,DVB-S,QPSK
+26=12111,V,20000,34,DVB-S,QPSK
+27=12124,H,20000,34,DVB-S,QPSK
+28=12142,V,20000,34,DVB-S,QPSK
+29=12155,H,20000,34,DVB-S,QPSK
+30=12172,V,20000,34,DVB-S,QPSK
+31=12185,H,20000,34,DVB-S,QPSK
+32=12224,V,21500,23,DVB-S,8PSK
+33=12239,H,21500,23,DVB-S,8PSK
+34=12253,V,21500,23,DVB-S,8PSK
+35=12268,H,21500,23,DVB-S,8PSK
+36=12282,V,21500,23,DVB-S,8PSK
+37=12297,H,20000,78,DVB-S,QPSK
+38=12311,V,21500,23,DVB-S,8PSK
+39=12326,H,20000,78,DVB-S,QPSK
+40=12341,V,20000,78,DVB-S,QPSK
+41=12355,H,20000,78,DVB-S,QPSK
+42=12370,V,20000,78,DVB-S,QPSK
+43=12384,H,20000,78,DVB-S,QPSK
+44=12399,V,20000,78,DVB-S,QPSK
+45=12414,H,20000,78,DVB-S,QPSK
+46=12428,V,20000,78,DVB-S,QPSK
+47=12443,H,20000,78,DVB-S,QPSK
+48=12457,V,20000,78,DVB-S,QPSK
+49=12472,H,20000,78,DVB-S,QPSK
+50=12486,V,20000,78,DVB-S,QPSK
+51=12501,H,20000,78,DVB-S,QPSK
+52=12516,V,20000,78,DVB-S,QPSK
+53=12530,H,20000,Auto,DVB-S,QPSK
+54=12545,V,20000,Auto,DVB-S,QPSK
+55=12559,H,20000,23,S2,8PSK
+56=12574,V,20000,Auto,DVB-S,QPSK
+57=12588,H,20000,Auto,DVB-S,QPSK
+58=12603,V,20000,Auto,DVB-S,QPSK
+59=12618,H,20000,Auto,DVB-S,QPSK
+60=12632,V,20000,Auto,DVB-S,QPSK
+61=12647,H,20000,Auto,DVB-S,QPSK
+62=12661,V,20000,Auto,DVB-S,QPSK
+63=12676,H,20000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini
new file mode 100644
index 000000000..aacb92c28
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2432.ini
@@ -0,0 +1,85 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2432
+2=Eutelsat 117 West A (116.8W)
+
+[DVB]
+0=76
+1=3720,V,27000,34,DVB-S,QPSK
+2=3744,V,2665,34,S2,8PSK
+3=3748,V,2100,78,DVB-S,QPSK
+4=3768,V,4800,34,S2,8PSK
+5=3772,V,3515,34,DVB-S,QPSK
+6=3786,V,6900,34,DVB-S,QPSK
+7=3793,V,4240,34,S2,QPSK
+8=3798,V,5225,56,S2,8PSK
+9=3804,V,1480,56,S2,8PSK
+10=3804,H,4000,34,DVB-S,QPSK
+11=3808,H,2170,34,DVB-S,QPSK
+12=3820,H,2000,34,S2,8PSK
+13=3824,H,1808,34,DVB-S,QPSK
+14=3835,V,19510,23,DVB-S,QPSK
+15=3850,H,4710,34,DVB-S,QPSK
+16=3853,H,1667,34,S2,8PSK
+17=3854,V,8333,23,S2,8PSK
+18=3868,V,8131,34,S2,8PSK
+19=3883,H,1350,34,S2,8PSK
+20=3885,H,1481,34,DVB-S,QPSK
+21=3888,V,1480,23,S2,8PSK
+22=3889,H,4181,34,DVB-S,QPSK
+23=3895,H,3609,34,DVB-S,QPSK
+24=3897,V,1480,34,DVB-S,QPSK
+25=3899,H,4167,34,S2,QPSK
+26=3903,H,1480,56,S2,8PSK
+27=3903,V,2200,78,DVB-S,QPSK
+28=3905,H,1600,34,S2,QPSK
+29=3908,H,2170,34,DVB-S,QPSK
+30=3911,H,2500,34,DVB-S,QPSK
+31=3914,H,2105,56,S2,8PSK
+32=3916,H,1520,34,DVB-S,QPSK
+33=3920,V,7320,34,DVB-S,QPSK
+34=3926,V,2222,34,DVB-S,QPSK
+35=3930,V,2310,78,DVB-S,QPSK
+36=3932,V,1447,34,S2,8PSK
+37=3940,H,29270,34,DVB-S,QPSK
+38=3949,V,11250,23,S2,8PSK
+39=3957,V,1595,56,S2,8PSK
+40=3960,V,1595,56,S2,8PSK
+41=3962,V,1800,34,S2,QPSK
+42=3968,V,7500,34,DVB-S,QPSK
+43=3969,H,1100,34,S2,QPSK
+44=3975,H,2170,34,S2,8PSK
+45=3976,V,2666,34,DVB-S,QPSK
+46=3984,V,3100,34,DVB-S,QPSK
+47=3989,V,2892,34,DVB-S,QPSK
+48=4009,V,6379,34,DVB-S,QPSK
+49=4015,V,3000,34,DVB-S,QPSK
+50=4031,V,15200,56,DVB-S,QPSK
+51=4044,H,3333,34,DVB-S,QPSK
+52=4049,H,3330,34,DVB-S,QPSK
+53=4052,V,4307,34,DVB-S,QPSK
+54=4056,V,1800,23,DVB-S,QPSK
+55=4064,H,19510,34,DVB-S,QPSK
+56=4075,H,2962,34,DVB-S,QPSK
+57=4084,H,3162,78,DVB-S,QPSK
+58=4090,H,5000,56,S2,8PSK
+59=4103,H,1600,23,S2,8PSK
+60=4106,H,3200,23,DVB-S,QPSK
+61=4109,H,2885,34,S2,QPSK
+62=4116,H,2900,34,S2,QPSK
+63=4120,V,30000,56,S2,8PSK
+64=4134,H,4400,34,DVB-S,QPSK
+65=4152,H,1321,35,S2,8PSK
+66=4155,H,1480,34,S2,8PSK
+67=4175,H,1850,Auto,S2,8PSK
+68=4178,H,2800,34,S2,8PSK
+69=4189,H,9760,34,DVB-S,QPSK
+70=12060,V,30000,34,DVB-S,8PSK
+71=12080,H,30000,34,DVB-S,8PSK
+72=12100,V,29000,34,DVB-S,8PSK
+73=12126,V,5400,34,DVB-S,QPSK
+74=12175,H,3704,34,DVB-S,QPSK
+75=12180,H,3000,12,DVB-S,QPSK
+76=12189,H,1660,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini
new file mode 100644
index 000000000..0272503f2
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2451.ini
@@ -0,0 +1,14 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2451
+2=Eutelsat 115 West A (114.9W)
+
+[DVB]
+0=5
+1=12041,V,1562,Auto,DVB-S,QPSK
+2=12044,V,1955,Auto,S2,QPSK
+3=12049,V,1955,Auto,S2,QPSK
+4=12063,H,3332,Auto,DVB-S,QPSK
+5=12087,V,3400,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini
new file mode 100644
index 000000000..0042e0ef1
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2470.ini
@@ -0,0 +1,64 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2470
+2=Eutelsat 113 West A (113.0W)
+
+[DVB]
+0=55
+1=3704,V,2222,34,S2,QPSK
+2=3709,V,3255,34,DVB-S,QPSK
+3=3714,V,2120,34,DVB-S,QPSK
+4=3731,V,3782,78,DVB-S,QPSK
+5=3734,H,3410,Auto,DVB-S,QPSK
+6=3736,V,3254,34,DVB-S,QPSK
+7=3744,V,2893,34,DVB-S,QPSK
+8=3752,V,2893,34,DVB-S,QPSK
+9=3760,V,2893,34,DVB-S,QPSK
+10=3764,H,2934,34,DVB-S,QPSK
+11=3765,V,3254,34,DVB-S,QPSK
+12=3768,H,2976,78,DVB-S,QPSK
+13=3769,V,3363,34,DVB-S,QPSK
+14=3773,V,2532,34,DVB-S,QPSK
+15=3773,H,2875,34,DVB-S,QPSK
+16=3780,H,4406,56,DVB-S,QPSK
+17=3784,H,2666,78,DVB-S,QPSK
+18=3787,H,2083,34,DVB-S,QPSK
+19=3821,H,3255,78,DVB-S,QPSK
+20=3825,H,3621,56,S2,8PSK
+21=3828,V,2550,56,DVB-S,QPSK
+22=3829,H,3620,56,S2,8PSK
+23=3834,H,3620,56,S2,8PSK
+24=3835,V,1807,34,DVB-S,QPSK
+25=3837,V,2550,78,DVB-S,QPSK
+26=3848,V,13842,34,S2,8PSK
+27=3848,H,2893,34,DVB-S,QPSK
+28=3853,H,3255,34,DVB-S,QPSK
+29=3857,H,2804,34,DVB-S,QPSK
+30=3863,H,3200,34,DVB-S,QPSK
+31=3867,H,2415,35,S2,8PSK
+32=3875,H,4166,34,DVB-S,QPSK
+33=3880,V,29270,34,DVB-S,QPSK
+34=3900,H,30000,35,S2,8PSK
+35=3920,V,29270,34,DVB-S,QPSK
+36=3955,H,2400,Auto,S2,QPSK
+37=4034,H,3551,34,DVB-S,QPSK
+38=4064,V,3080,34,S2,8PSK
+39=4080,V,2920,34,DVB-S,QPSK
+40=4140,H,20008,56,S2,8PSK
+41=11989,V,3750,34,DVB-S,QPSK
+42=11994,V,4340,23,DVB-S,QPSK
+43=12028,H,2600,Auto,DVB-S,QPSK
+44=12046,H,14200,35,S2,8PSK
+45=12089,H,11719,34,DVB-S,QPSK
+46=12110,H,2170,Auto,DVB-S,QPSK
+47=12126,V,6022,Auto,DVB-S,QPSK
+48=12136,V,3255,Auto,DVB-S,QPSK
+49=12151,V,3255,Auto,DVB-S,QPSK
+50=12157,V,3038,Auto,DVB-S,QPSK
+51=12161,H,1480,34,DVB-S,QPSK
+52=12165,H,3333,Auto,DVB-S,QPSK
+53=12165,V,3255,Auto,DVB-S,QPSK
+54=12172,V,3333,Auto,DVB-S,QPSK
+55=12193,V,3255,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini
new file mode 100644
index 000000000..c71cfdd79
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2489.ini
@@ -0,0 +1,40 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2489
+2=Anik F2 (111.1W)
+
+[DVB]
+0=31
+1=4168,V,9737,12,S2,8PSK
+2=11745,V,20500,23,DVB-S,8PSK
+3=11758,H,20500,23,DVB-S,8PSK
+4=11770,V,3270,Auto,DVB-S,QPSK
+5=11819,H,20500,23,DVB-S,8PSK
+6=11837,V,20500,23,DVB-S,8PSK
+7=11850,H,20500,23,DVB-S,8PSK
+8=11880,H,20500,23,DVB-S,8PSK
+9=11898,V,20500,23,DVB-S,8PSK
+10=11928,V,20500,23,DVB-S,8PSK
+11=11972,H,20500,23,DVB-S,8PSK
+12=11989,V,20500,23,DVB-S,8PSK
+13=12002,H,19510,34,DVB-S,QPSK
+14=12020,V,20500,23,DVB-S,8PSK
+15=12033,H,20500,23,DVB-S,8PSK
+16=12050,V,20500,23,DVB-S,8PSK
+17=12063,H,19510,34,DVB-S,QPSK
+18=12081,V,20500,23,DVB-S,8PSK
+19=12094,H,19510,34,DVB-S,QPSK
+20=12111,V,19510,34,DVB-S,QPSK
+21=12142,V,20500,23,DVB-S,8PSK
+22=12155,H,20500,23,DVB-S,8PSK
+23=12172,V,19510,34,DVB-S,QPSK
+24=12185,H,20500,23,DVB-S,8PSK
+25=19776,H,15000,34,DVB-S,QPSK
+26=19794,H,15000,34,DVB-S,QPSK
+27=19814,H,15000,34,DVB-S,QPSK
+28=19905,H,22500,34,DVB-S,QPSK
+29=19932,H,22500,34,DVB-S,QPSK
+30=19966,H,15000,12,DVB-S,QPSK
+31=20002,H,15000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini
new file mode 100644
index 000000000..0fb566b48
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2500.ini
@@ -0,0 +1,38 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2500
+2=DirecTV 5/EchoStar 10/11 (110.0W)
+
+[DVB]
+0=29
+1=12224,V,20000,78,DVB-S,QPSK
+2=12239,H,20000,78,DVB-S,QPSK
+3=12253,V,20000,78,DVB-S,QPSK
+4=12268,H,21500,23,DVB-S,8PSK
+5=12282,V,20000,78,DVB-S,QPSK
+6=12297,H,20000,78,DVB-S,QPSK
+7=12311,V,21500,23,DVB-S,8PSK
+8=12326,H,20000,78,DVB-S,QPSK
+9=12341,V,20000,78,DVB-S,QPSK
+10=12355,H,20000,78,DVB-S,QPSK
+11=12370,V,20000,78,DVB-S,QPSK
+12=12384,H,20000,56,DVB-S,QPSK
+13=12399,V,21500,23,DVB-S,8PSK
+14=12414,H,20000,78,DVB-S,QPSK
+15=12428,V,20000,78,DVB-S,QPSK
+16=12443,H,20000,78,DVB-S,QPSK
+17=12472,H,21500,23,DVB-S,8PSK
+18=12486,V,21500,23,DVB-S,8PSK
+19=12501,H,21500,23,DVB-S,8PSK
+20=12516,V,20000,78,DVB-S,QPSK
+21=12530,H,21500,23,DVB-S,8PSK
+22=12545,V,21500,23,DVB-S,8PSK
+23=12559,H,20000,78,DVB-S,QPSK
+24=12574,V,20000,56,DVB-S,8PSK
+25=12588,H,20000,56,DVB-S,QPSK
+26=12603,V,20000,56,DVB-S,QPSK
+27=12618,H,20000,Auto,DVB-S,QPSK
+28=12632,V,21500,23,DVB-S,8PSK
+29=12661,V,21500,23,DVB-S,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini
new file mode 100644
index 000000000..41b4e2981
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2527.ini
@@ -0,0 +1,79 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2527
+2=Anik F1R/G1 (107.3W)
+
+[DVB]
+0=70
+1=3734,V,1665,56,DVB-S,QPSK
+2=3780,V,28346,78,DVB-S,QPSK
+3=3807,V,6500,12,DVB-S,QPSK
+4=3825,V,6500,12,DVB-S,QPSK
+5=3840,H,30000,34,S2,8PSK
+6=3860,V,30000,23,S2,8PSK
+7=3913,V,7078,23,S2,8PSK
+8=3920,H,30000,34,DVB-S,8PSK
+9=3924,V,3000,78,DVB-S,QPSK
+10=3948,V,14630,34,DVB-S,QPSK
+11=3962,H,9120,78,DVB-S,QPSK
+12=4020,V,30000,56,S2,8PSK
+13=4040,H,30000,34,S2,8PSK
+14=4060,V,28346,78,DVB-S,QPSK
+15=4080,H,30000,34,S2,8PSK
+16=4100,V,28346,78,DVB-S,QPSK
+17=4107,H,7440,56,DVB-S,QPSK
+18=4117,H,6200,56,DVB-S,QPSK
+19=4140,V,30000,56,S2,8PSK
+20=4160,H,30000,34,S2,8PSK
+21=11092,V,22000,89,DVB-S,8PSK
+22=11092,H,22000,89,DVB-S,8PSK
+23=11122,V,22000,89,DVB-S,8PSK
+24=11122,H,22000,89,DVB-S,8PSK
+25=11152,V,22000,89,DVB-S,8PSK
+26=11152,H,22000,89,DVB-S,8PSK
+27=11183,V,22000,89,DVB-S,8PSK
+28=11183,H,22000,89,DVB-S,8PSK
+29=11592,V,22000,56,DVB-S,8PSK
+30=11592,H,22000,89,DVB-S,8PSK
+31=11622,V,22000,56,DVB-S,8PSK
+32=11622,H,22000,89,DVB-S,8PSK
+33=11652,V,22000,56,DVB-S,8PSK
+34=11683,V,22000,56,DVB-S,8PSK
+35=11683,H,20500,56,DVB-S,8PSK
+36=11715,V,21000,34,DVB-S,8PSK
+37=11728,H,19510,34,DVB-S,QPSK
+38=11745,V,19510,34,DVB-S,QPSK
+39=11758,H,19510,34,DVB-S,QPSK
+40=11776,V,19510,34,DVB-S,QPSK
+41=11789,H,19510,34,DVB-S,QPSK
+42=11806,V,19510,34,DVB-S,QPSK
+43=11819,H,19510,34,DVB-S,QPSK
+44=11837,V,19510,34,DVB-S,QPSK
+45=11850,H,19510,34,DVB-S,QPSK
+46=11867,V,19510,34,DVB-S,QPSK
+47=11880,H,19510,34,DVB-S,QPSK
+48=11898,V,19510,34,DVB-S,QPSK
+49=11902,H,5859,34,DVB-S,QPSK
+50=11912,H,5859,34,DVB-S,QPSK
+51=11928,V,19510,34,DVB-S,QPSK
+52=11933,H,5859,34,DVB-S,QPSK
+53=11941,H,5859,34,DVB-S,QPSK
+54=11949,H,5859,34,DVB-S,QPSK
+55=11959,V,19510,34,DVB-S,QPSK
+56=11972,H,19510,34,DVB-S,QPSK
+57=11989,V,20500,23,DVB-S,8PSK
+58=12002,H,19510,34,DVB-S,QPSK
+59=12020,V,19510,34,DVB-S,QPSK
+60=12033,H,19510,34,DVB-S,QPSK
+61=12050,V,19510,34,DVB-S,QPSK
+62=12063,H,19510,34,DVB-S,QPSK
+63=12081,V,20500,23,DVB-S,8PSK
+64=12094,H,19510,34,DVB-S,QPSK
+65=12111,V,19510,34,DVB-S,QPSK
+66=12124,H,19510,34,DVB-S,QPSK
+67=12142,V,19510,34,DVB-S,QPSK
+68=12155,H,19510,34,DVB-S,QPSK
+69=12172,V,19510,34,DVB-S,QPSK
+70=12185,H,19510,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini
new file mode 100644
index 000000000..d573433b8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2550.ini
@@ -0,0 +1,37 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2550
+2=AMC 15/18 (105.0W)
+
+[DVB]
+0=28
+1=3720,V,19510,34,DVB-S,QPSK
+2=3760,V,28068,34,DVB-S,QPSK
+3=3780,H,30000,34,S2,8PSK
+4=3840,V,30000,56,S2,8PSK
+5=3860,H,30000,56,S2,8PSK
+6=3900,H,19510,34,DVB-S,QPSK
+7=3940,H,30000,56,S2,8PSK
+8=4000,V,30000,56,S2,8PSK
+9=4020,H,30000,56,S2,8PSK
+10=4060,H,19510,34,DVB-S,QPSK
+11=4080,V,30000,56,S2,8PSK
+12=4100,H,19510,34,DVB-S,QPSK
+13=4120,V,19510,34,DVB-S,QPSK
+14=4140,H,19510,34,DVB-S,QPSK
+15=4160,V,30000,56,S2,8PSK
+16=4180,H,19510,34,DVB-S,QPSK
+17=11706,V,6620,34,DVB-S,QPSK
+18=11716,V,6620,34,DVB-S,QPSK
+19=11724,V,6113,34,DVB-S,QPSK
+20=11729,H,3979,34,DVB-S,QPSK
+21=11734,V,6113,34,DVB-S,QPSK
+22=11756,V,6113,34,DVB-S,QPSK
+23=11766,V,4411,Auto,DVB-S,QPSK
+24=11766,H,6113,34,DVB-S,QPSK
+25=11830,V,6620,Auto,DVB-S,QPSK
+26=11834,H,13235,Auto,DVB-S,QPSK
+27=11856,V,3548,12,DVB-S,QPSK
+28=12122,H,1000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini
new file mode 100644
index 000000000..1fcd35643
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2570.ini
@@ -0,0 +1,73 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2570
+2=SES 3/Spaceway 1 & DirecTV 10/12 (103.0W)
+
+[DVB]
+0=64
+1=3740,V,29270,78,DVB-S,QPSK
+2=3760,H,30000,34,S2,8PSK
+3=3780,V,28800,56,S2,8PSK
+4=3800,H,29270,78,DVB-S,QPSK
+5=3820,V,29270,34,DVB-S,QPSK
+6=3840,H,26681,34,DVB-S,QPSK
+7=3860,V,30000,56,S2,8PSK
+8=3891,V,14400,23,S2,8PSK
+9=3904,V,6667,23,S2,8PSK
+10=3906,H,6511,34,DVB-S,QPSK
+11=3913,H,2927,34,DVB-S,QPSK
+12=3920,H,3150,56,DVB-S,QPSK
+13=3924,H,2734,Auto,S2,QPSK
+14=3960,H,30000,56,S2,8PSK
+15=3972,V,14800,56,DVB-S,QPSK
+16=4040,H,30000,23,S2,8PSK
+17=4081,H,7233,34,DVB-S,QPSK
+18=4089,H,5923,56,S2,8PSK
+19=4091,V,14029,34,DVB-S,QPSK
+20=4120,H,30000,56,S2,8PSK
+21=4140,V,30000,56,S2,8PSK
+22=4160,H,26681,34,DVB-S,QPSK
+23=11760,H,30000,56,S2,8PSK
+24=11840,H,30000,56,S2,8PSK
+25=11880,H,30000,56,S2,8PSK
+26=11940,V,20000,34,DVB-S,QPSK
+27=11985,H,4600,34,S2,8PSK
+28=12009,H,4600,34,S2,8PSK
+29=12015,H,4600,56,DVB-S,QPSK
+30=12025,H,4600,34,S2,8PSK
+31=12065,H,4232,56,DVB-S,QPSK
+32=12071,H,4600,34,S2,8PSK
+33=12076,V,4250,56,S2,8PSK
+34=12077,H,4600,34,S2,8PSK
+35=12083,H,4600,34,S2,8PSK
+36=12089,H,4600,34,S2,8PSK
+37=12095,H,4600,34,S2,8PSK
+38=12145,V,20000,34,DVB-S,QPSK
+39=12157,H,4600,34,S2,8PSK
+40=12175,H,4600,34,S2,8PSK
+41=12182,V,25000,34,DVB-S,QPSK
+42=18327,H,30000,23,S2,QPSK
+43=18327,V,30000,23,S2,QPSK
+44=18367,H,30000,23,S2,QPSK
+45=18367,V,30000,23,S2,QPSK
+46=18407,H,30000,23,S2,QPSK
+47=18407,V,30000,23,S2,QPSK
+48=18447,H,30000,23,S2,QPSK
+49=18447,V,30000,23,S2,QPSK
+50=18487,H,30000,23,S2,QPSK
+51=18487,V,30000,23,S2,QPSK
+52=18527,H,30000,23,S2,QPSK
+53=18527,V,30000,23,S2,QPSK
+54=18567,H,30000,23,S2,QPSK
+55=18567,V,30000,23,S2,QPSK
+56=18607,H,30000,23,S2,QPSK
+57=18607,V,30000,23,S2,QPSK
+58=18648,V,30000,23,S2,QPSK
+59=19741,H,30000,34,S2,QPSK
+60=19741,V,30000,34,S2,QPSK
+61=19804,H,30000,34,S2,QPSK
+62=19804,V,30000,34,S2,QPSK
+63=19866,H,30000,34,S2,QPSK
+64=19866,V,30000,34,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini
new file mode 100644
index 000000000..322d683c1
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2590.ini
@@ -0,0 +1,55 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2590
+2=DirecTV 4S/8/SES 1 (101.0W)
+
+[DVB]
+0=46
+1=3710,V,4340,34,DVB-S,QPSK
+2=3716,V,4775,35,S2,8PSK
+3=3722,V,5600,34,S2,8PSK
+4=3773,V,4442,34,DVB-S,QPSK
+5=3920,V,30000,56,S2,8PSK
+6=3953,V,2734,56,DVB-S,QPSK
+7=3957,V,2734,56,DVB-S,QPSK
+8=3961,V,2734,56,DVB-S,QPSK
+9=3974,V,5924,56,DVB-S,QPSK
+10=4020,H,28000,34,S2,8PSK
+11=11705,V,3650,34,S2,QPSK
+12=11795,H,4342,56,DVB-S,QPSK
+13=11820,H,20000,34,DVB-S,QPSK
+14=12172,H,15000,Auto,DVB-S,QPSK
+15=12224,V,20000,Auto,DVB-S,QPSK
+16=12239,H,20000,Auto,DVB-S,QPSK
+17=12253,V,20000,Auto,DVB-S,QPSK
+18=12268,H,20000,23,DVB-S,QPSK
+19=12282,V,20000,Auto,DVB-S,QPSK
+20=12297,H,20000,Auto,DVB-S,QPSK
+21=12311,V,20000,Auto,DVB-S,QPSK
+22=12326,H,20000,Auto,DVB-S,QPSK
+23=12341,V,20000,Auto,DVB-S,QPSK
+24=12355,H,20000,Auto,DVB-S,QPSK
+25=12370,V,20000,Auto,DVB-S,QPSK
+26=12384,H,20000,Auto,DVB-S,QPSK
+27=12399,V,20000,Auto,DVB-S,QPSK
+28=12414,H,20000,Auto,DVB-S,QPSK
+29=12428,V,20000,Auto,DVB-S,QPSK
+30=12443,H,20000,Auto,DVB-S,QPSK
+31=12457,V,20000,Auto,DVB-S,QPSK
+32=12472,H,20000,Auto,DVB-S,QPSK
+33=12486,V,20000,Auto,DVB-S,QPSK
+34=12501,H,20000,Auto,DVB-S,QPSK
+35=12516,V,20000,Auto,DVB-S,QPSK
+36=12530,H,20000,Auto,DVB-S,QPSK
+37=12545,V,20000,Auto,DVB-S,QPSK
+38=12559,H,20000,Auto,DVB-S,QPSK
+39=12574,V,20000,Auto,DVB-S,QPSK
+40=12588,H,20000,23,DVB-S,QPSK
+41=12603,V,20000,Auto,DVB-S,QPSK
+42=12618,H,20000,Auto,DVB-S,QPSK
+43=12632,V,20000,Auto,DVB-S,QPSK
+44=12647,H,20000,Auto,DVB-S,QPSK
+45=12661,V,20000,Auto,DVB-S,QPSK
+46=12676,H,20000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini
new file mode 100644
index 000000000..e3200b7cd
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2608.ini
@@ -0,0 +1,81 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2608
+2=DirecTV 14/Galaxy 16/Spaceway 2 & DirecTV 11 (99.2W)
+
+[DVB]
+0=72
+1=3720,H,8700,34,S2,8PSK
+2=3735,H,3775,34,DVB-S,QPSK
+3=3740,V,30000,56,S2,QPSK
+4=3770,H,1220,34,S2,QPSK
+5=3785,H,4850,34,S2,8PSK
+6=3789,H,1666,56,DVB-S,QPSK
+7=3791,H,1665,56,DVB-S,QPSK
+8=3793,V,7030,12,S2,QPSK
+9=3795,H,3255,34,DVB-S,QPSK
+10=3811,H,8030,34,DVB-S,QPSK
+11=3820,V,26000,34,DVB-S,QPSK
+12=3900,V,28000,34,DVB-S,QPSK
+13=3904,H,3125,78,DVB-S,QPSK
+14=3912,H,10833,89,S2,8PSK
+15=3924,H,3125,78,DVB-S,QPSK
+16=3925,V,3979,23,DVB-S,QPSK
+17=3928,H,3125,78,DVB-S,QPSK
+18=3930,V,3680,23,DVB-S,QPSK
+19=3931,H,1562,56,DVB-S,QPSK
+20=3938,H,1561,78,DVB-S,QPSK
+21=3940,V,27600,56,S2,QPSK
+22=3953,H,3125,78,DVB-S,QPSK
+23=3977,H,2555,Auto,DVB-S,QPSK
+24=3980,V,26470,56,DVB-S,QPSK
+25=4000,H,26400,34,DVB-S,QPSK
+26=4006,V,5833,34,S2,QPSK
+27=4060,V,27780,56,DVB-S,QPSK
+28=4080,H,27780,56,DVB-S,QPSK
+29=4120,H,30000,910,S2,8PSK
+30=4140,V,30000,910,S2,8PSK
+31=4145,H,3308,34,DVB-S,QPSK
+32=4193,V,6620,23,DVB-S,QPSK
+33=11765,V,4000,34,DVB-S,QPSK
+34=11782,V,3979,34,DVB-S,QPSK
+35=11787,V,3979,34,DVB-S,QPSK
+36=11792,V,3979,34,DVB-S,QPSK
+37=11800,H,30000,34,S2,QPSK
+38=11804,V,3979,34,DVB-S,QPSK
+39=11809,V,3979,34,DVB-S,QPSK
+40=11815,V,3979,34,DVB-S,QPSK
+41=11820,V,3979,34,DVB-S,QPSK
+42=11825,V,3979,34,DVB-S,QPSK
+43=11825,H,3979,34,DVB-S,QPSK
+44=11830,V,3979,34,DVB-S,QPSK
+45=11830,H,3979,34,DVB-S,QPSK
+46=11836,V,3979,34,DVB-S,QPSK
+47=11836,H,3979,34,DVB-S,QPSK
+48=11842,H,3979,34,DVB-S,QPSK
+49=11848,H,3979,34,DVB-S,QPSK
+50=11854,H,3979,34,DVB-S,QPSK
+51=11865,H,3979,34,DVB-S,QPSK
+52=11871,H,3979,34,DVB-S,QPSK
+53=11876,H,3979,34,DVB-S,QPSK
+54=11882,H,3979,34,DVB-S,QPSK
+55=11884,V,3979,34,DVB-S,QPSK
+56=11888,H,3979,34,DVB-S,QPSK
+57=11889,V,3979,34,DVB-S,QPSK
+58=11894,H,3979,34,DVB-S,QPSK
+59=11895,V,3979,34,DVB-S,QPSK
+60=11900,V,3979,34,DVB-S,QPSK
+61=11905,V,3979,34,DVB-S,QPSK
+62=11905,H,3979,34,DVB-S,QPSK
+63=11910,V,3979,34,DVB-S,QPSK
+64=11911,H,3979,34,DVB-S,QPSK
+65=11916,V,3979,34,DVB-S,QPSK
+66=11917,H,3979,34,DVB-S,QPSK
+67=11960,H,30000,78,DVB-S,QPSK
+68=11980,V,30000,56,DVB-S,QPSK
+69=12020,V,20000,910,S2,8PSK
+70=12040,H,26665,23,DVB-S,QPSK
+71=12093,H,6620,34,DVB-S,QPSK
+72=12100,V,30000,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini
new file mode 100644
index 000000000..1a888553a
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2630.ini
@@ -0,0 +1,57 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2630
+2=Galaxy 19 (97.0W)
+
+[DVB]
+0=48
+1=3706,V,6111,34,DVB-S,QPSK
+2=3760,V,31456,35,S2,8PSK
+3=3780,H,29270,34,DVB-S,QPSK
+4=3800,V,29860,910,S2,8PSK
+5=3831,V,11800,56,DVB-S,QPSK
+6=3839,V,2940,78,DVB-S,QPSK
+7=3847,V,2200,34,DVB-S,QPSK
+8=3851,V,3532,34,DVB-S,QPSK
+9=3857,V,2940,Auto,DVB-S,QPSK
+10=3880,V,30000,56,S2,8PSK
+11=3896,H,20000,34,DVB-S,QPSK
+12=3914,H,7000,34,S2,8PSK
+13=3922,V,3703,34,DVB-S,QPSK
+14=3940,H,30000,56,S2,8PSK
+15=3960,V,29300,34,DVB-S,QPSK
+16=3985,V,3600,Auto,S2,8PSK
+17=4001,V,1481,89,S2,8PSK
+18=4009,V,4407,56,S2,8PSK
+19=4027,V,7200,23,S2,8PSK
+20=4034,H,6111,34,DVB-S,QPSK
+21=4060,H,32362,34,DVB-S,QPSK
+22=4080,V,29856,910,S2,8PSK
+23=4100,H,29856,910,S2,8PSK
+24=4120,V,30000,56,S2,8PSK
+25=4140,H,29856,910,S2,8PSK
+26=4160,V,29856,910,S2,8PSK
+27=4167,H,6922,56,S2,8PSK
+28=11836,V,20770,34,DVB-S,QPSK
+29=11842,H,22000,34,DVB-S,QPSK
+30=11867,V,22000,34,DVB-S,QPSK
+31=11898,V,22000,34,DVB-S,QPSK
+32=11904,H,22000,34,DVB-S,QPSK
+33=11929,V,22000,34,DVB-S,QPSK
+34=11936,H,20000,34,DVB-S,QPSK
+35=11960,V,22000,34,DVB-S,QPSK
+36=11966,H,22000,34,DVB-S,QPSK
+37=12022,V,22000,34,DVB-S,QPSK
+38=12028,H,21991,34,DVB-S,QPSK
+39=12053,V,22000,34,DVB-S,QPSK
+40=12060,H,22000,34,DVB-S,QPSK
+41=12084,V,22000,34,DVB-S,QPSK
+42=12090,H,20000,34,DVB-S,QPSK
+43=12115,V,22425,34,DVB-S,QPSK
+44=12122,H,20000,34,DVB-S,QPSK
+45=12146,V,22000,34,DVB-S,QPSK
+46=12152,H,20000,34,DVB-S,QPSK
+47=12177,V,23000,34,DVB-S,QPSK
+48=12184,H,21991,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini
new file mode 100644
index 000000000..f3c4e0de6
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2650.ini
@@ -0,0 +1,83 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2650
+2=Galaxy 3C/Intelsat 30/Spaceway 3 (95.0W)
+
+[DVB]
+0=74
+1=3785,V,6922,56,S2,8PSK
+2=3800,H,29270,Auto,DVB-S,QPSK
+3=3827,H,6922,56,S2,8PSK
+4=3829,V,13000,56,S2,8PSK
+5=3884,V,1035,34,S2,QPSK
+6=3889,V,3074,34,DVB-S,QPSK
+7=3893,V,3074,34,DVB-S,QPSK
+8=3896,V,2000,34,S2,8PSK
+9=3901,V,1836,34,S2,8PSK
+10=3911,V,3074,34,DVB-S,QPSK
+11=3911,H,15000,56,S2,8PSK
+12=3924,V,3074,34,DVB-S,QPSK
+13=3929,V,3074,34,DVB-S,QPSK
+14=3935,V,2000,34,S2,8PSK
+15=3940,V,2000,34,S2,8PSK
+16=3943,V,3074,34,DVB-S,QPSK
+17=3950,V,2000,34,S2,8PSK
+18=3956,V,3302,34,S2,8PSK
+19=3965,V,1035,34,S2,8PSK
+20=3970,V,1035,34,S2,QPSK
+21=3974,V,3074,34,DVB-S,QPSK
+22=3980,V,1035,34,S2,QPSK
+23=3984,V,1035,34,S2,QPSK
+24=3988,V,3074,34,DVB-S,QPSK
+25=3992,V,3074,34,DVB-S,QPSK
+26=3996,V,3074,34,DVB-S,QPSK
+27=4000,H,30000,910,S2,8PSK
+28=4031,H,14035,34,S2,8PSK
+29=4060,V,31250,34,S2,8PSK
+30=4080,H,31250,34,S2,8PSK
+31=4120,H,29270,Auto,DVB-S,QPSK
+32=4173,V,2221,Auto,DVB-S,QPSK
+33=11480,V,22500,Auto,DVB-S,QPSK
+34=11480,H,20000,23,DVB-S,QPSK
+35=11510,V,20000,23,DVB-S,QPSK
+36=11510,H,22500,Auto,DVB-S,QPSK
+37=11539,V,22500,Auto,DVB-S,QPSK
+38=11539,H,22500,Auto,DVB-S,QPSK
+39=11568,V,20000,23,DVB-S,QPSK
+40=11568,H,22500,Auto,DVB-S,QPSK
+41=11597,V,21500,56,S2,QPSK
+42=11597,H,22500,Auto,DVB-S,QPSK
+43=11626,V,22500,Auto,DVB-S,QPSK
+44=11626,H,22500,Auto,DVB-S,QPSK
+45=11655,V,22500,Auto,DVB-S,QPSK
+46=11655,H,22500,Auto,DVB-S,QPSK
+47=11685,V,22500,Auto,DVB-S,QPSK
+48=11685,H,22500,Auto,DVB-S,QPSK
+49=11720,H,20000,23,DVB-S,QPSK
+50=11750,H,30000,23,S2,QPSK
+51=11780,H,20760,34,DVB-S,QPSK
+52=11810,H,30000,23,S2,QPSK
+53=11840,H,20000,23,DVB-S,QPSK
+54=11900,H,20000,23,DVB-S,QPSK
+55=11930,H,30000,23,S2,QPSK
+56=11930,H,20000,23,DVB-S,QPSK
+57=11960,H,20000,23,DVB-S,QPSK
+58=11960,V,20000,23,DVB-S,QPSK
+59=11975,H,20000,23,DVB-S,QPSK
+60=11990,H,20000,23,DVB-S,QPSK
+61=11990,V,20000,23,DVB-S,QPSK
+62=12020,V,21000,56,S2,QPSK
+63=12035,H,21000,56,S2,QPSK
+64=12050,H,20000,34,DVB-S,QPSK
+65=12050,V,21000,56,S2,QPSK
+66=12080,H,20000,23,DVB-S,QPSK
+67=12080,V,20000,23,DVB-S,QPSK
+68=12095,H,20000,23,DVB-S,QPSK
+69=12110,H,2220,Auto,DVB-S,QPSK
+70=12110,V,20000,23,DVB-S,QPSK
+71=12140,H,20000,23,DVB-S,QPSK
+72=12140,V,20000,23,DVB-S,QPSK
+73=12155,H,20000,23,DVB-S,QPSK
+74=12170,V,20000,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini
new file mode 100644
index 000000000..ccb7e8531
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2669.ini
@@ -0,0 +1,16 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2669
+2=Galaxy 25 (93.1W)
+
+[DVB]
+0=7
+1=4036,V,19852,56,DVB-S,QPSK
+2=4053,V,6617,56,DVB-S,QPSK
+3=4180,H,26470,56,DVB-S,QPSK
+4=11986,V,5075,Auto,DVB-S,QPSK
+5=12010,V,11574,Auto,DVB-S,QPSK
+6=12124,V,6615,Auto,DVB-S,QPSK
+7=12126,V,2220,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini
new file mode 100644
index 000000000..e3c73e65c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2690.ini
@@ -0,0 +1,97 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2690
+2=Galaxy 17/Nimiq 6 (91.0W)
+
+[DVB]
+0=88
+1=3720,H,28800,35,S2,8PSK
+2=3740,V,31250,34,S2,8PSK
+3=3751,H,14410,56,S2,8PSK
+4=3764,H,7500,56,S2,8PSK
+5=3780,V,29270,34,DVB-S,QPSK
+6=3800,H,31250,34,S2,8PSK
+7=3820,V,30000,56,DVB-S,QPSK
+8=3840,H,29270,78,DVB-S,QPSK
+9=3860,V,31250,34,S2,8PSK
+10=3866,H,6620,12,DVB-S,QPSK
+11=3920,H,30000,34,S2,8PSK
+12=3925,V,4249,23,S2,8PSK
+13=3934,V,2480,78,DVB-S,QPSK
+14=3952,V,10833,56,S2,8PSK
+15=3960,H,29270,78,DVB-S,QPSK
+16=3984,V,22500,56,S2,8PSK
+17=4000,H,30000,56,S2,8PSK
+18=4020,V,31250,34,S2,8PSK
+19=4040,H,31250,34,S2,8PSK
+20=4066,V,6051,56,S2,8PSK
+21=4076,V,3000,34,DVB-S,QPSK
+22=4080,H,30000,34,S2,8PSK
+23=4100,V,30000,56,S2,8PSK
+24=4115,H,19510,34,DVB-S,QPSK
+25=4134,H,6960,56,S2,8PSK
+26=4140,V,31250,34,S2,8PSK
+27=4160,H,31250,34,S2,8PSK
+28=4180,V,30000,56,S2,8PSK
+29=11740,V,30000,78,DVB-S,QPSK
+30=11925,V,3979,34,DVB-S,QPSK
+31=11930,V,3979,34,DVB-S,QPSK
+32=11935,V,3979,34,DVB-S,QPSK
+33=11940,V,3979,34,DVB-S,QPSK
+34=11945,V,3979,34,DVB-S,QPSK
+35=11950,V,3979,34,DVB-S,QPSK
+36=11952,H,5859,Auto,DVB-S,QPSK
+37=11955,V,3979,34,DVB-S,QPSK
+38=11965,V,3979,Auto,DVB-S,QPSK
+39=11970,V,3979,Auto,DVB-S,QPSK
+40=11973,H,6111,34,DVB-S,QPSK
+41=11975,V,3979,Auto,DVB-S,QPSK
+42=11980,V,3979,Auto,DVB-S,QPSK
+43=11985,V,3979,Auto,DVB-S,QPSK
+44=11987,H,6111,Auto,DVB-S,QPSK
+45=11990,V,3979,Auto,DVB-S,QPSK
+46=11995,V,3979,Auto,DVB-S,QPSK
+47=11995,H,6111,34,DVB-S,QPSK
+48=12010,V,11574,34,DVB-S,QPSK
+49=12020,V,3979,34,DVB-S,QPSK
+50=12025,V,3979,34,DVB-S,QPSK
+51=12030,V,3979,34,DVB-S,QPSK
+52=12035,V,3979,34,DVB-S,QPSK
+53=12076,H,13000,Auto,DVB-S,QPSK
+54=12115,H,13235,Auto,DVB-S,QPSK
+55=12130,H,13000,34,DVB-S,QPSK
+56=12180,V,5632,34,DVB-S,QPSK
+57=12224,V,20000,78,DVB-S,QPSK
+58=12239,H,20000,56,DVB-S,QPSK
+59=12253,V,20000,78,DVB-S,QPSK
+60=12268,H,20000,78,DVB-S,QPSK
+61=12282,V,20000,Auto,DVB-S,QPSK
+62=12297,H,20000,56,DVB-S,QPSK
+63=12311,V,20000,78,DVB-S,QPSK
+64=12326,H,20000,78,DVB-S,QPSK
+65=12341,V,20000,Auto,DVB-S,QPSK
+66=12355,H,20000,78,DVB-S,QPSK
+67=12370,V,20000,Auto,DVB-S,QPSK
+68=12384,H,20000,78,DVB-S,QPSK
+69=12399,V,20000,78,DVB-S,QPSK
+70=12414,H,20000,56,DVB-S,QPSK
+71=12428,V,20000,56,DVB-S,QPSK
+72=12443,H,20000,56,DVB-S,QPSK
+73=12457,V,20000,Auto,DVB-S,QPSK
+74=12472,H,20000,78,DVB-S,QPSK
+75=12486,V,20000,56,DVB-S,QPSK
+76=12501,H,20000,56,DVB-S,QPSK
+77=12516,V,20000,78,DVB-S,QPSK
+78=12530,H,20000,78,DVB-S,QPSK
+79=12545,V,20000,78,DVB-S,QPSK
+80=12559,H,20000,78,DVB-S,QPSK
+81=12574,V,20000,78,DVB-S,QPSK
+82=12588,H,20000,78,DVB-S,QPSK
+83=12603,V,20000,56,DVB-S,QPSK
+84=12618,H,20000,56,DVB-S,QPSK
+85=12632,V,20000,56,DVB-S,QPSK
+86=12647,H,20000,56,DVB-S,QPSK
+87=12661,V,20000,56,DVB-S,QPSK
+88=12676,H,20000,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini
new file mode 100644
index 000000000..8e5aa2688
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2710.ini
@@ -0,0 +1,69 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2710
+2=Galaxy 28 (89.0W)
+
+[DVB]
+0=60
+1=3840,V,29860,910,S2,8PSK
+2=3860,H,26000,Auto,S2,8PSK
+3=3880,V,29860,910,S2,QPSK
+4=3900,H,32360,34,DVB-S,QPSK
+5=3920,V,29860,910,S2,8PSK
+6=3980,H,32360,34,DVB-S,QPSK
+7=4005,V,6111,34,DVB-S,QPSK
+8=4014,V,6111,34,DVB-S,QPSK
+9=4060,H,32362,34,S2,QPSK
+10=4110,H,2835,Auto,S2,8PSK
+11=4154,V,4434,Auto,DVB-S,QPSK
+12=4166,H,7440,Auto,DVB-S,QPSK
+13=4175,H,7440,Auto,DVB-S,QPSK
+14=4185,H,7440,Auto,DVB-S,QPSK
+15=11711,H,6620,Auto,DVB-S,QPSK
+16=11724,H,6500,Auto,DVB-S,QPSK
+17=11732,H,4440,Auto,DVB-S,QPSK
+18=11745,H,7030,Auto,DVB-S,QPSK
+19=11747,H,6620,Auto,DVB-S,QPSK
+20=11756,H,6620,Auto,DVB-S,QPSK
+21=11800,H,30000,23,S2,8PSK
+22=11845,H,6510,Auto,DVB-S,QPSK
+23=11884,H,2788,45,S2,QPSK
+24=11920,V,30000,78,DVB-S,QPSK
+25=11920,H,30000,23,S2,8PSK
+26=11925,H,3979,34,DVB-S,QPSK
+27=11930,H,3979,34,DVB-S,QPSK
+28=11935,H,3979,34,DVB-S,QPSK
+29=11940,H,3979,34,DVB-S,QPSK
+30=11945,H,3979,34,DVB-S,QPSK
+31=11950,H,3979,34,DVB-S,QPSK
+32=11955,H,3979,34,DVB-S,QPSK
+33=11960,H,28800,34,DVB-S,QPSK
+34=11965,H,3979,34,DVB-S,QPSK
+35=11970,V,3979,34,DVB-S,QPSK
+36=11970,H,3979,34,DVB-S,QPSK
+37=11975,H,3979,34,DVB-S,QPSK
+38=11980,H,3979,34,DVB-S,QPSK
+39=11985,H,3979,34,DVB-S,QPSK
+40=11989,V,6111,34,DVB-S,QPSK
+41=11990,H,3979,34,DVB-S,QPSK
+42=11995,H,3979,34,DVB-S,QPSK
+43=12000,H,28800,34,DVB-S,QPSK
+44=12009,V,6111,34,DVB-S,QPSK
+45=12035,V,6111,34,DVB-S,QPSK
+46=12047,V,6111,Auto,DVB-S,QPSK
+47=12100,H,30000,78,DVB-S,QPSK
+48=12121,H,2676,34,DVB-S,QPSK
+49=12140,H,30000,78,DVB-S,QPSK
+50=12160,V,30000,78,DVB-S,QPSK
+51=12164,H,2785,34,DVB-S,QPSK
+52=12167,H,2785,34,DVB-S,QPSK
+53=12171,H,2785,34,DVB-S,QPSK
+54=12174,H,2785,34,DVB-S,QPSK
+55=12178,H,2785,34,DVB-S,QPSK
+56=12181,H,2785,34,DVB-S,QPSK
+57=12185,H,2785,34,DVB-S,QPSK
+58=12188,H,2785,34,DVB-S,QPSK
+59=12192,H,2785,34,DVB-S,QPSK
+60=12195,H,2785,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini
new file mode 100644
index 000000000..9b148a046
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2728.ini
@@ -0,0 +1,11 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2728
+2=TKSat 1 (87.2W)
+
+[DVB]
+0=2
+1=11479,V,15000,Auto,S2,QPSK
+2=12486,V,21702,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini
new file mode 100644
index 000000000..fdb17c5c0
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2730.ini
@@ -0,0 +1,41 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2730
+2=SES 2 (87.0W)
+
+[DVB]
+0=32
+1=3743,V,5000,56,S2,8PSK
+2=3753,V,8680,34,DVB-S,QPSK
+3=3760,H,26680,Auto,DVB-S,QPSK
+4=3780,V,28800,56,DVB-S,QPSK
+5=3842,H,6150,78,DVB-S,QPSK
+6=3887,H,18400,23,S2,8PSK
+7=3949,V,4164,34,S2,8PSK
+8=3954,V,2500,34,DVB-S,QPSK
+9=4000,H,29125,56,S2,8PSK
+10=4026,H,2300,34,S2,8PSK
+11=4044,H,3910,34,DVB-S,QPSK
+12=4146,H,6789,34,DVB-S,QPSK
+13=4149,H,5063,34,DVB-S,QPSK
+14=4188,V,3027,Auto,DVB-S,QPSK
+15=11725,H,3675,23,DVB-S,QPSK
+16=11737,V,8333,23,DVB-S,QPSK
+17=11745,H,3979,34,DVB-S,QPSK
+18=11750,V,7320,78,DVB-S,QPSK
+19=11800,H,2686,34,DVB-S,QPSK
+20=11804,H,1250,35,S2,8PSK
+21=11811,H,11150,35,S2,8PSK
+22=11820,V,30000,56,DVB-S,QPSK
+23=11900,V,30000,23,DVB-S,QPSK
+24=11960,H,29270,34,DVB-S,QPSK
+25=12008,V,5000,12,DVB-S,QPSK
+26=12009,H,2170,34,DVB-S,QPSK
+27=12044,V,3200,23,S2,8PSK
+28=12064,V,6510,56,DVB-S,QPSK
+29=12152,H,15000,Auto,S2,8PSK
+30=12165,H,6110,34,DVB-S,QPSK
+31=12175,H,4342,Auto,DVB-S,QPSK
+32=12184,V,3500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini
new file mode 100644
index 000000000..8f2358d56
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2750.ini
@@ -0,0 +1,19 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2750
+2=AMC 16 (85.0W)
+
+[DVB]
+0=10
+1=11966,H,5632,Auto,DVB-S,QPSK
+2=11980,H,29270,Auto,DVB-S,QPSK
+3=12000,V,29270,Auto,DVB-S,QPSK
+4=12106,V,6113,Auto,DVB-S,QPSK
+5=12116,V,6113,Auto,DVB-S,QPSK
+6=12130,H,13021,Auto,DVB-S,QPSK
+7=12144,H,3979,Auto,DVB-S,QPSK
+8=12146,V,6111,Auto,DVB-S,QPSK
+9=12164,V,6111,Auto,DVB-S,QPSK
+10=12194,H,3978,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini
new file mode 100644
index 000000000..253d2cced
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2760.ini
@@ -0,0 +1,20 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2760
+2=Brasilsat B4 (84.0W)
+
+[DVB]
+0=11
+1=3643,H,3565,34,DVB-S,QPSK
+2=3650,V,3460,12,DVB-S,QPSK
+3=3684,V,3200,34,DVB-S,QPSK
+4=3690,V,3330,34,DVB-S,QPSK
+5=3720,H,2222,34,DVB-S,QPSK
+6=3725,H,2222,34,DVB-S,QPSK
+7=3785,H,4500,56,DVB-S,QPSK
+8=3806,H,1666,34,S2,8PSK
+9=3852,V,3333,34,S2,8PSK
+10=4135,H,2500,34,DVB-S,QPSK
+11=4152,V,3255,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini
new file mode 100644
index 000000000..12cbcc729
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2770.ini
@@ -0,0 +1,38 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2770
+2=AMC 9 (83.0W)
+
+[DVB]
+0=29
+1=3804,V,4167,34,DVB-S,QPSK
+2=3810,V,2400,34,DVB-S,QPSK
+3=3813,V,2222,34,DVB-S,QPSK
+4=3817,V,2879,34,DVB-S,QPSK
+5=3825,V,4035,56,S2,8PSK
+6=3831,V,2960,56,DVB-S,QPSK
+7=3912,H,2615,Auto,DVB-S,QPSK
+8=11745,H,4232,56,DVB-S,QPSK
+9=11751,H,4232,56,DVB-S,QPSK
+10=11757,H,4232,56,DVB-S,QPSK
+11=11763,H,4232,56,DVB-S,QPSK
+12=11769,H,4232,56,DVB-S,QPSK
+13=11775,H,4232,56,DVB-S,QPSK
+14=11790,H,4232,Auto,DVB-S,QPSK
+15=11803,H,4232,Auto,DVB-S,QPSK
+16=11809,H,4232,Auto,DVB-S,QPSK
+17=11815,H,4232,Auto,DVB-S,QPSK
+18=11864,H,3979,Auto,DVB-S,QPSK
+19=11871,H,13000,Auto,DVB-S,QPSK
+20=11874,V,6111,34,DVB-S,QPSK
+21=11889,H,13025,Auto,DVB-S,QPSK
+22=11926,V,6511,34,DVB-S,QPSK
+23=11953,V,3979,Auto,DVB-S,QPSK
+24=11960,H,5000,34,DVB-S,QPSK
+25=12002,H,3979,Auto,DVB-S,QPSK
+26=12011,H,3979,Auto,DVB-S,QPSK
+27=12051,V,13022,Auto,DVB-S,QPSK
+28=12160,H,29269,Auto,DVB-S,QPSK
+29=12180,V,29271,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini
new file mode 100644
index 000000000..7080fc519
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2780.ini
@@ -0,0 +1,40 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2780
+2=Nimiq 4 (82.0W)
+
+[DVB]
+0=31
+1=12224,V,21500,23,DVB-S,8PSK
+2=12239,H,21500,23,DVB-S,8PSK
+3=12253,V,21500,23,DVB-S,8PSK
+4=12268,H,21500,23,DVB-S,8PSK
+5=12282,V,21500,23,DVB-S,8PSK
+6=12297,H,21500,23,DVB-S,8PSK
+7=12311,V,21500,23,DVB-S,8PSK
+8=12326,H,21500,23,DVB-S,8PSK
+9=12341,V,21500,23,DVB-S,8PSK
+10=12355,H,21500,23,DVB-S,8PSK
+11=12370,V,21500,23,DVB-S,8PSK
+12=12384,H,21500,23,DVB-S,8PSK
+13=12399,V,21500,23,DVB-S,8PSK
+14=12414,H,21500,23,DVB-S,8PSK
+15=12443,H,20000,78,DVB-S,QPSK
+16=12457,V,21500,23,DVB-S,8PSK
+17=12472,H,21500,23,DVB-S,8PSK
+18=12486,V,21500,23,DVB-S,8PSK
+19=12501,H,21500,23,DVB-S,8PSK
+20=12516,V,21500,23,DVB-S,8PSK
+21=12530,H,21500,23,DVB-S,8PSK
+22=12545,V,21500,23,DVB-S,8PSK
+23=12559,H,21500,23,DVB-S,8PSK
+24=12574,V,21500,23,DVB-S,8PSK
+25=12588,H,21500,23,DVB-S,8PSK
+26=12603,V,21500,23,DVB-S,8PSK
+27=12618,H,21500,23,DVB-S,8PSK
+28=12632,V,21500,23,DVB-S,8PSK
+29=12647,H,21500,23,DVB-S,8PSK
+30=12661,V,21500,23,DVB-S,8PSK
+31=12676,H,20000,Auto,DVB-S,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini
new file mode 100644
index 000000000..61b29bb93
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2812.ini
@@ -0,0 +1,29 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2812
+2=Sky Mexico 1 (78.8W)
+
+[DVB]
+0=20
+1=11720,H,30000,Auto,DVB-S,QPSK
+2=11740,V,30000,Auto,DVB-S,QPSK
+3=11800,H,30000,Auto,DVB-S,QPSK
+4=11820,V,30000,Auto,DVB-S,QPSK
+5=11880,H,30000,Auto,DVB-S,QPSK
+6=11900,V,30000,Auto,DVB-S,QPSK
+7=11920,H,30000,Auto,DVB-S,QPSK
+8=11940,V,30000,Auto,DVB-S,QPSK
+9=11960,H,30000,Auto,DVB-S,QPSK
+10=11980,V,30000,Auto,DVB-S,QPSK
+11=12000,H,30000,Auto,DVB-S,QPSK
+12=12020,V,30000,Auto,DVB-S,QPSK
+13=12040,H,30000,Auto,DVB-S,QPSK
+14=12060,V,30000,Auto,DVB-S,QPSK
+15=12080,H,30000,Auto,DVB-S,QPSK
+16=12100,V,30000,Auto,DVB-S,QPSK
+17=12120,H,30000,Auto,DVB-S,QPSK
+18=12140,V,30000,Auto,DVB-S,QPSK
+19=12160,H,30000,Auto,DVB-S,QPSK
+20=12180,V,30000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini
new file mode 100644
index 000000000..0aa5cc903
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2820.ini
@@ -0,0 +1,23 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2820
+2=Simón Bolívar (78.0W)
+
+[DVB]
+0=14
+1=3838,V,6670,34,DVB-S,QPSK
+2=3885,V,23000,34,DVB-S,QPSK
+3=3912,V,3100,Auto,DVB-S,QPSK
+4=3916,V,3002,Auto,DVB-S,QPSK
+5=3922,V,3002,Auto,DVB-S,QPSK
+6=11323,H,3100,Auto,DVB-S,QPSK
+7=11380,H,42355,34,S2,QPSK
+8=11410,V,29500,34,S2,QPSK
+9=11509,V,2900,34,DVB-S,QPSK
+10=11512,V,3100,34,DVB-S,QPSK
+11=11520,V,4444,34,DVB-S,QPSK
+12=11535,H,4340,34,DVB-S,QPSK
+13=11624,V,3000,34,DVB-S,QPSK
+14=11731,H,28126,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini
new file mode 100644
index 000000000..c6536b22b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2830.ini
@@ -0,0 +1,41 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2830
+2=EchoStar 8/QuetzSat 1 (77.0W)
+
+[DVB]
+0=32
+1=12224,V,22500,56,DVB-S,QPSK
+2=12239,H,22500,56,DVB-S,QPSK
+3=12253,V,20000,56,DVB-S,QPSK
+4=12268,H,22500,56,DVB-S,QPSK
+5=12282,V,22500,56,DVB-S,QPSK
+6=12297,H,20000,56,DVB-S,QPSK
+7=12311,V,22500,56,DVB-S,QPSK
+8=12326,H,22500,56,DVB-S,QPSK
+9=12341,V,22500,56,DVB-S,QPSK
+10=12355,H,20000,56,DVB-S,QPSK
+11=12370,V,22500,56,DVB-S,QPSK
+12=12384,H,22500,56,DVB-S,QPSK
+13=12399,V,20000,56,DVB-S,QPSK
+14=12414,H,22500,56,DVB-S,QPSK
+15=12428,V,20000,56,DVB-S,QPSK
+16=12443,H,22500,56,DVB-S,QPSK
+17=12457,V,22500,56,DVB-S,QPSK
+18=12472,H,20000,56,DVB-S,QPSK
+19=12486,V,20000,56,DVB-S,QPSK
+20=12501,H,22500,56,DVB-S,QPSK
+21=12516,V,22500,56,DVB-S,QPSK
+22=12530,H,22500,56,DVB-S,QPSK
+23=12545,V,22500,56,DVB-S,QPSK
+24=12559,H,22500,56,DVB-S,QPSK
+25=12574,V,22500,56,DVB-S,QPSK
+26=12588,H,20000,56,DVB-S,QPSK
+27=12603,V,22500,56,DVB-S,QPSK
+28=12618,H,22500,56,DVB-S,QPSK
+29=12632,V,22500,56,DVB-S,QPSK
+30=12647,H,22500,56,DVB-S,QPSK
+31=12661,V,20000,56,DVB-S,QPSK
+32=12676,H,22500,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini
new file mode 100644
index 000000000..cc6088079
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2850.ini
@@ -0,0 +1,98 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2850
+2=Star One C3 (75.0W)
+
+[DVB]
+0=89
+1=3627,H,3255,34,DVB-S,QPSK
+2=3632,H,3333,34,DVB-S,QPSK
+3=3636,H,3333,34,DVB-S,QPSK
+4=3649,H,3002,34,DVB-S,QPSK
+5=3660,V,30000,23,S2,QPSK
+6=3665,H,5000,34,S2,QPSK
+7=3680,H,2400,34,S2,8PSK
+8=3684,H,2500,34,S2,QPSK
+9=3684,V,2963,34,DVB-S,QPSK
+10=3689,V,2666,34,DVB-S,QPSK
+11=3690,H,5000,34,S2,QPSK
+12=3697,V,6990,34,S2,QPSK
+13=3703,V,2400,23,DVB-S,QPSK
+14=3705,H,4280,34,S2,QPSK
+15=3706,V,3600,34,DVB-S,QPSK
+16=3709,H,3333,34,S2,QPSK
+17=3711,V,3255,34,DVB-S,QPSK
+18=3714,H,3333,34,DVB-S,QPSK
+19=3715,V,2535,34,DVB-S,QPSK
+20=3722,H,3565,34,DVB-S,QPSK
+21=3727,H,5000,34,S2,QPSK
+22=3727,V,5833,34,S2,QPSK
+23=3733,V,4444,34,DVB-S,QPSK
+24=3735,H,5833,23,S2,QPSK
+25=3736,V,2033,89,S2,QPSK
+26=3740,V,2072,56,S2,QPSK
+27=3745,V,5833,34,S2,QPSK
+28=3747,H,6250,34,S2,QPSK
+29=3754,H,6250,34,S2,QPSK
+30=3765,V,4170,34,S2,QPSK
+31=3770,H,17500,34,S2,QPSK
+32=3771,V,4170,34,S2,QPSK
+33=3776,V,5000,34,S2,8PSK
+34=3780,V,2222,78,DVB-S,QPSK
+35=3784,V,2500,34,S2,QPSK
+36=3788,V,1111,34,DVB-S,QPSK
+37=3828,V,4340,34,DVB-S,QPSK
+38=3833,V,3255,34,DVB-S,QPSK
+39=3837,V,2532,34,DVB-S,QPSK
+40=3846,V,4340,56,DVB-S,QPSK
+41=3852,V,6247,34,S2,QPSK
+42=3863,V,3209,34,DVB-S,QPSK
+43=3868,V,4283,34,DVB-S,QPSK
+44=3874,V,6250,34,S2,QPSK
+45=3883,H,3928,34,DVB-S,QPSK
+46=3885,V,5000,23,S2,QPSK
+47=3890,H,2170,34,DVB-S,QPSK
+48=3890,V,3704,34,DVB-S,QPSK
+49=3895,H,5833,34,S2,QPSK
+50=3901,V,5000,34,S2,8PSK
+51=3907,V,2232,34,DVB-S,QPSK
+52=3910,H,12500,23,S2,QPSK
+53=3911,V,2222,34,DVB-S,QPSK
+54=3917,V,3750,34,S2,QPSK
+55=3925,V,5000,34,S2,QPSK
+56=3927,H,14100,23,S2,8PSK
+57=3935,V,8000,34,DVB-S,QPSK
+58=3936,H,3195,35,S2,QPSK
+59=3943,V,3260,34,DVB-S,QPSK
+60=3954,V,6666,34,S2,QPSK
+61=3979,V,3255,34,DVB-S,QPSK
+62=3986,V,5590,34,DVB-S,QPSK
+63=3994,V,6250,34,S2,QPSK
+64=4048,V,3330,56,DVB-S,QPSK
+65=4052,V,2500,34,S2,QPSK
+66=4055,V,2500,34,DVB-S,QPSK
+67=4066,H,5833,23,S2,QPSK
+68=4073,H,5833,34,S2,8PSK
+69=4080,H,5833,23,S2,QPSK
+70=4086,H,4170,34,S2,QPSK
+71=4091,H,4170,34,S2,QPSK
+72=4096,H,4170,34,S2,QPSK
+73=4100,V,30000,56,S2,8PSK
+74=4105,H,3633,34,S2,QPSK
+75=4120,H,20840,34,S2,QPSK
+76=4136,H,4170,34,S2,QPSK
+77=4144,H,5000,34,S2,QPSK
+78=4151,H,5000,34,S2,QPSK
+79=4157,H,5000,34,S2,QPSK
+80=4164,H,5000,34,S2,QPSK
+81=4165,V,5000,34,S2,QPSK
+82=4170,H,5000,34,S2,8PSK
+83=4171,V,5000,34,S2,QPSK
+84=4175,H,5000,34,S2,QPSK
+85=4177,V,5000,34,S2,QPSK
+86=4183,H,5000,34,S2,QPSK
+87=4193,V,4762,34,S2,QPSK
+88=4197,V,2073,56,S2,QPSK
+89=11764,V,3480,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini
new file mode 100644
index 000000000..6c39037ae
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2873.ini
@@ -0,0 +1,40 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2873
+2=Nimiq 5 (72.7W)
+
+[DVB]
+0=31
+1=12224,V,21500,23,DVB-S,8PSK
+2=12239,H,21500,23,DVB-S,8PSK
+3=12253,V,21500,23,DVB-S,8PSK
+4=12268,H,21500,23,DVB-S,8PSK
+5=12282,V,21500,23,DVB-S,8PSK
+6=12297,H,21500,23,DVB-S,8PSK
+7=12311,V,21500,23,DVB-S,8PSK
+8=12326,H,21500,23,DVB-S,8PSK
+9=12341,V,21500,23,DVB-S,8PSK
+10=12355,H,21500,23,DVB-S,8PSK
+11=12370,V,21500,23,DVB-S,8PSK
+12=12384,H,21500,23,DVB-S,8PSK
+13=12399,V,21500,23,DVB-S,8PSK
+14=12428,V,21500,23,DVB-S,8PSK
+15=12443,H,21500,23,DVB-S,8PSK
+16=12457,V,21500,23,DVB-S,8PSK
+17=12472,H,21500,23,DVB-S,8PSK
+18=12486,V,21500,23,DVB-S,8PSK
+19=12501,H,21500,23,DVB-S,8PSK
+20=12516,V,21500,23,DVB-S,8PSK
+21=12530,H,21500,23,DVB-S,8PSK
+22=12545,V,21500,23,DVB-S,8PSK
+23=12559,H,21500,23,DVB-S,8PSK
+24=12574,V,21500,23,DVB-S,8PSK
+25=12588,H,21500,23,DVB-S,8PSK
+26=12603,V,21500,23,DVB-S,8PSK
+27=12618,H,21500,23,DVB-S,8PSK
+28=12632,V,21500,23,DVB-S,8PSK
+29=12647,H,21500,23,DVB-S,8PSK
+30=12661,V,21500,23,DVB-S,8PSK
+31=12676,H,21500,23,DVB-S,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini
new file mode 100644
index 000000000..2abb9f716
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2880.ini
@@ -0,0 +1,38 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2880
+2=AMC 6 (72.0W)
+
+[DVB]
+0=29
+1=11703,V,3979,Auto,DVB-S,QPSK
+2=11709,V,4600,34,S2,8PSK
+3=11715,V,4600,34,S2,8PSK
+4=11720,V,4600,34,S2,8PSK
+5=11725,V,3979,Auto,DVB-S,QPSK
+6=11729,V,3979,Auto,DVB-S,QPSK
+7=11734,V,3979,Auto,DVB-S,QPSK
+8=11745,H,3979,Auto,DVB-S,QPSK
+9=11746,V,3979,Auto,DVB-S,QPSK
+10=11752,V,3979,Auto,DVB-S,QPSK
+11=11760,V,4600,34,S2,8PSK
+12=11766,V,4600,34,S2,8PSK
+13=11778,V,4600,34,S2,8PSK
+14=11817,H,5000,34,DVB-S,QPSK
+15=11921,V,3979,Auto,DVB-S,QPSK
+16=11927,V,3979,Auto,DVB-S,QPSK
+17=11986,V,3979,34,DVB-S,QPSK
+18=11995,V,3979,34,DVB-S,QPSK
+19=12004,V,6889,Auto,DVB-S,QPSK
+20=12020,H,3979,Auto,DVB-S,QPSK
+21=12028,V,4600,34,S2,8PSK
+22=12036,H,6111,Auto,DVB-S,QPSK
+23=12040,V,3979,Auto,DVB-S,QPSK
+24=12045,V,1580,Auto,DVB-S,QPSK
+25=12046,H,6111,Auto,DVB-S,QPSK
+26=12055,V,6890,56,DVB-S,QPSK
+27=12114,V,13000,Auto,DVB-S,QPSK
+28=12130,V,6111,Auto,DVB-S,QPSK
+29=12188,H,6511,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini
new file mode 100644
index 000000000..5a3d34b2c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2881.ini
@@ -0,0 +1,112 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2881
+2=AMC 6/Arsat 1 (71.9W)
+
+[DVB]
+0=103
+1=11175,V,4200,34,DVB-S,QPSK
+2=11179,V,3100,34,DVB-S,QPSK
+3=11466,V,3500,34,DVB-S,QPSK
+4=11540,H,3330,34,DVB-S,QPSK
+5=11544,H,6660,Auto,DVB-S,QPSK
+6=11546,V,12000,23,DVB-S,QPSK
+7=11552,H,2591,34,DVB-S,QPSK
+8=11555,H,1904,Auto,DVB-S,QPSK
+9=11564,H,3200,34,DVB-S,QPSK
+10=11568,H,3350,34,DVB-S,QPSK
+11=11573,H,3333,34,DVB-S,QPSK
+12=11577,H,3333,34,DVB-S,QPSK
+13=11577,V,2400,56,DVB-S,QPSK
+14=11581,H,1325,34,DVB-S,QPSK
+15=11582,V,2850,34,S2,8PSK
+16=11584,H,2655,78,DVB-S,QPSK
+17=11595,H,1904,78,DVB-S,QPSK
+18=11598,H,2500,34,DVB-S,QPSK
+19=11640,V,8500,Auto,DVB-S,QPSK
+20=11651,V,1904,78,DVB-S,QPSK
+21=11657,H,1904,78,DVB-S,QPSK
+22=11660,H,2500,Auto,S2,8PSK
+23=11660,V,2943,Auto,DVB-S,QPSK
+24=11667,H,6665,34,S2,QPSK
+25=11670,V,30000,56,S2,QPSK
+26=11675,H,1904,34,DVB-S,QPSK
+27=11678,H,1904,34,DVB-S,QPSK
+28=11686,V,2222,34,DVB-S,QPSK
+29=11703,V,3979,Auto,DVB-S,QPSK
+30=11708,H,6660,34,S2,8PSK
+31=11709,V,4600,34,S2,8PSK
+32=11715,V,4600,34,S2,8PSK
+33=11718,H,6660,12,S2,8PSK
+34=11718,V,6660,34,S2,8PSK
+35=11720,V,4600,34,S2,8PSK
+36=11725,V,3979,Auto,DVB-S,QPSK
+37=11728,V,3300,34,DVB-S,QPSK
+38=11729,V,3979,Auto,DVB-S,QPSK
+39=11731,H,3124,34,DVB-S,QPSK
+40=11734,H,2655,34,DVB-S,QPSK
+41=11734,V,3979,Auto,DVB-S,QPSK
+42=11745,V,2373,34,DVB-S,QPSK
+43=11745,H,3979,Auto,DVB-S,QPSK
+44=11746,V,3979,Auto,DVB-S,QPSK
+45=11752,H,2373,34,DVB-S,QPSK
+46=11752,V,3979,Auto,DVB-S,QPSK
+47=11755,H,2963,Auto,S2,QPSK
+48=11756,V,3200,34,DVB-S,QPSK
+49=11760,V,4600,34,S2,8PSK
+50=11766,V,4600,34,S2,8PSK
+51=11778,V,4600,34,S2,8PSK
+52=11779,V,3600,Auto,DVB-S,QPSK
+53=11794,V,3600,Auto,DVB-S,QPSK
+54=11805,V,3300,Auto,DVB-S,QPSK
+55=11809,V,3350,Auto,DVB-S,QPSK
+56=11817,H,5000,34,DVB-S,QPSK
+57=11817,V,3333,34,DVB-S,QPSK
+58=11829,V,3330,34,DVB-S,QPSK
+59=11848,V,3333,34,DVB-S,QPSK
+60=11851,V,3350,34,S2,QPSK
+61=11853,V,2343,34,DVB-S,QPSK
+62=11861,V,3330,34,DVB-S,QPSK
+63=11866,V,3300,34,DVB-S,QPSK
+64=11870,H,14089,23,S2,QPSK
+65=11876,H,6666,Auto,DVB-S,QPSK
+66=11877,V,2355,34,DVB-S,QPSK
+67=11882,H,3333,34,S2,QPSK
+68=11888,V,3330,34,DVB-S,QPSK
+69=11892,H,3333,Auto,DVB-S,QPSK
+70=11896,H,3330,34,DVB-S,QPSK
+71=11897,V,3200,34,DVB-S,QPSK
+72=11907,V,2373,34,DVB-S,QPSK
+73=11910,V,2600,34,S2,8PSK
+74=11915,V,2600,34,DVB-S,QPSK
+75=11921,V,3979,Auto,DVB-S,QPSK
+76=11927,V,3979,Auto,DVB-S,QPSK
+77=11986,V,3979,34,DVB-S,QPSK
+78=11995,V,3979,34,DVB-S,QPSK
+79=12004,V,6889,Auto,DVB-S,QPSK
+80=12020,H,3979,Auto,DVB-S,QPSK
+81=12028,V,4600,34,S2,8PSK
+82=12036,H,6111,Auto,DVB-S,QPSK
+83=12040,V,3979,Auto,DVB-S,QPSK
+84=12045,V,1580,Auto,DVB-S,QPSK
+85=12046,H,6111,Auto,DVB-S,QPSK
+86=12051,V,2200,56,DVB-S,QPSK
+87=12054,H,6620,34,S2,8PSK
+88=12055,V,2150,Auto,S2,8PSK
+89=12058,V,2223,56,DVB-S,QPSK
+90=12058,H,7400,23,DVB-S,QPSK
+91=12063,V,4170,23,DVB-S,QPSK
+92=12066,H,2500,34,DVB-S,QPSK
+93=12067,V,3333,34,DVB-S,QPSK
+94=12070,H,2000,56,DVB-S,QPSK
+95=12074,V,2400,56,DVB-S,QPSK
+96=12075,H,1660,56,S2,8PSK
+97=12080,H,7200,34,S2,QPSK
+98=12083,V,2850,78,DVB-S,QPSK
+99=12086,V,4170,23,DVB-S,QPSK
+100=12092,H,4000,23,DVB-S,QPSK
+101=12114,V,13000,Auto,DVB-S,QPSK
+102=12130,V,6111,Auto,DVB-S,QPSK
+103=12188,H,6511,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini
new file mode 100644
index 000000000..591ba2fe4
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2882.ini
@@ -0,0 +1,84 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2882
+2=Arsat 1 (71.8W)
+
+[DVB]
+0=75
+1=11175,V,4200,34,DVB-S,QPSK
+2=11179,V,3100,34,DVB-S,QPSK
+3=11466,V,3500,34,DVB-S,QPSK
+4=11540,H,3330,34,DVB-S,QPSK
+5=11544,H,6660,Auto,DVB-S,QPSK
+6=11546,V,12000,23,DVB-S,QPSK
+7=11552,H,2591,34,DVB-S,QPSK
+8=11555,H,1904,Auto,DVB-S,QPSK
+9=11564,H,3200,34,DVB-S,QPSK
+10=11568,H,3350,34,DVB-S,QPSK
+11=11573,H,3333,34,DVB-S,QPSK
+12=11577,H,3333,34,DVB-S,QPSK
+13=11577,V,2400,56,DVB-S,QPSK
+14=11581,H,1325,34,DVB-S,QPSK
+15=11582,V,2850,34,S2,8PSK
+16=11584,H,2655,78,DVB-S,QPSK
+17=11595,H,1904,78,DVB-S,QPSK
+18=11598,H,2500,34,DVB-S,QPSK
+19=11640,V,8500,Auto,DVB-S,QPSK
+20=11651,V,1904,78,DVB-S,QPSK
+21=11657,H,1904,78,DVB-S,QPSK
+22=11660,H,2500,Auto,S2,8PSK
+23=11660,V,2943,Auto,DVB-S,QPSK
+24=11667,H,6665,34,S2,QPSK
+25=11670,V,30000,56,S2,QPSK
+26=11675,H,1904,34,DVB-S,QPSK
+27=11678,H,1904,34,DVB-S,QPSK
+28=11686,V,2222,34,DVB-S,QPSK
+29=11708,H,6660,34,S2,8PSK
+30=11718,H,6660,12,S2,8PSK
+31=11718,V,6660,34,S2,8PSK
+32=11728,V,3300,34,DVB-S,QPSK
+33=11731,H,3124,34,DVB-S,QPSK
+34=11734,H,2655,34,DVB-S,QPSK
+35=11745,V,2373,34,DVB-S,QPSK
+36=11752,H,2373,34,DVB-S,QPSK
+37=11755,H,2963,Auto,S2,QPSK
+38=11756,V,3200,34,DVB-S,QPSK
+39=11779,V,3600,Auto,DVB-S,QPSK
+40=11794,V,3600,Auto,DVB-S,QPSK
+41=11805,V,3300,Auto,DVB-S,QPSK
+42=11809,V,3350,Auto,DVB-S,QPSK
+43=11817,V,3333,34,DVB-S,QPSK
+44=11829,V,3330,34,DVB-S,QPSK
+45=11848,V,3333,34,DVB-S,QPSK
+46=11851,V,3350,34,S2,QPSK
+47=11853,V,2343,34,DVB-S,QPSK
+48=11861,V,3330,34,DVB-S,QPSK
+49=11866,V,3300,34,DVB-S,QPSK
+50=11870,H,14089,23,S2,QPSK
+51=11876,H,6666,Auto,DVB-S,QPSK
+52=11877,V,2355,34,DVB-S,QPSK
+53=11882,H,3333,34,S2,QPSK
+54=11888,V,3330,34,DVB-S,QPSK
+55=11892,H,3333,Auto,DVB-S,QPSK
+56=11896,H,3330,34,DVB-S,QPSK
+57=11897,V,3200,34,DVB-S,QPSK
+58=11907,V,2373,34,DVB-S,QPSK
+59=11910,V,2600,34,S2,8PSK
+60=11915,V,2600,34,DVB-S,QPSK
+61=12051,V,2200,56,DVB-S,QPSK
+62=12054,H,6620,34,S2,8PSK
+63=12055,V,2150,Auto,S2,8PSK
+64=12058,H,7400,23,DVB-S,QPSK
+65=12058,V,2223,56,DVB-S,QPSK
+66=12063,V,4170,23,DVB-S,QPSK
+67=12066,H,2500,34,DVB-S,QPSK
+68=12067,V,3333,34,DVB-S,QPSK
+69=12070,H,2000,56,DVB-S,QPSK
+70=12074,V,2400,56,DVB-S,QPSK
+71=12075,H,1660,56,S2,8PSK
+72=12080,H,7200,34,S2,QPSK
+73=12083,V,2850,78,DVB-S,QPSK
+74=12086,V,4170,23,DVB-S,QPSK
+75=12092,H,4000,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini
new file mode 100644
index 000000000..3a4144bf6
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2900.ini
@@ -0,0 +1,72 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2900
+2=Star One C2/C4 (70.0W)
+
+[DVB]
+0=63
+1=3628,H,3000,34,DVB-S,QPSK
+2=3632,H,4688,34,DVB-S,QPSK
+3=3642,H,4583,34,S2,8PSK
+4=3644,V,3214,34,DVB-S,QPSK
+5=3648,V,2170,34,DVB-S,QPSK
+6=3650,H,5000,23,S2,8PSK
+7=3652,V,2777,23,DVB-S,QPSK
+8=3656,H,3393,34,DVB-S,QPSK
+9=3657,V,7500,23,DVB-S,QPSK
+10=3665,V,2400,34,DVB-S,QPSK
+11=3665,H,3818,34,DVB-S,QPSK
+12=3667,V,2500,56,DVB-S,QPSK
+13=3672,H,7500,23,S2,8PSK
+14=3674,V,6666,34,DVB-S,QPSK
+15=3680,H,7500,23,S2,8PSK
+16=3685,V,5000,34,S2,8PSK
+17=3689,H,7500,23,S2,8PSK
+18=3690,V,2220,34,DVB-S,QPSK
+19=3695,H,3599,34,DVB-S,QPSK
+20=3702,V,15000,34,S2,8PSK
+21=3704,H,3750,23,S2,8PSK
+22=3711,V,2170,34,DVB-S,QPSK
+23=3715,V,5000,34,S2,8PSK
+24=3753,V,6220,34,DVB-S,QPSK
+25=3808,V,7500,23,S2,QPSK
+26=3816,V,6666,23,S2,8PSK
+27=3825,V,6666,23,S2,8PSK
+28=3833,V,4073,56,S2,8PSK
+29=3874,V,7500,23,S2,8PSK
+30=3887,V,7500,Auto,S2,8PSK
+31=3895,V,7500,23,S2,8PSK
+32=3906,V,7500,23,S2,8PSK
+33=3916,V,7500,23,S2,8PSK
+34=3940,V,30000,23,S2,8PSK
+35=3947,H,7200,23,DVB-S,QPSK
+36=3955,H,4400,34,DVB-S,QPSK
+37=3959,H,1875,34,DVB-S,QPSK
+38=3965,V,4069,23,DVB-S,QPSK
+39=3967,H,7500,23,S2,8PSK
+40=3970,V,1852,56,DVB-S,QPSK
+41=3973,V,4000,23,DVB-S,QPSK
+42=3973,H,7500,23,S2,8PSK
+43=3978,V,3617,56,DVB-S,QPSK
+44=3982,V,4573,34,S2,8PSK
+45=3985,H,2170,34,DVB-S,QPSK
+46=3990,V,7400,34,S2,8PSK
+47=3993,H,12416,Auto,DVB-S,QPSK
+48=3996,V,2300,34,DVB-S,QPSK
+49=4047,V,7143,34,DVB-S,QPSK
+50=10974,H,29890,34,DVB-S,QPSK
+51=11014,H,29890,35,S2,QPSK
+52=11130,V,29890,34,DVB-S,QPSK
+53=11170,V,29890,34,DVB-S,QPSK
+54=11740,H,29890,34,S2,8PSK
+55=11780,H,29890,34,DVB-S,QPSK
+56=11820,H,29890,34,DVB-S,QPSK
+57=11880,H,41500,34,DVB-S,QPSK
+58=11940,H,29890,34,DVB-S,QPSK
+59=11960,V,29900,35,S2,QPSK
+60=12020,V,41500,34,DVB-S,QPSK
+61=12080,V,29890,34,S2,8PSK
+62=12120,V,29890,34,DVB-S,QPSK
+63=12160,V,28890,35,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini
new file mode 100644
index 000000000..b144562e4
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2930.ini
@@ -0,0 +1,16 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2930
+2=AMC 4 (67.0W)
+
+[DVB]
+0=7
+1=11720,V,28888,34,DVB-S,QPSK
+2=11760,V,28888,34,DVB-S,QPSK
+3=11800,V,28888,34,DVB-S,QPSK
+4=11840,V,28888,34,DVB-S,QPSK
+5=11880,V,28888,34,DVB-S,QPSK
+6=11920,V,28888,34,DVB-S,QPSK
+7=12162,V,9600,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini
new file mode 100644
index 000000000..3b6a477fc
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2950.ini
@@ -0,0 +1,51 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2950
+2=Star One C1 (65.0W)
+
+[DVB]
+0=42
+1=3650,V,4440,Auto,DVB-S,QPSK
+2=3669,V,4686,34,S2,8PSK
+3=3670,H,9043,34,S2,QPSK
+4=3687,H,3214,Auto,DVB-S,QPSK
+5=3691,H,4000,23,S2,8PSK
+6=3697,H,4400,23,S2,8PSK
+7=3720,H,2963,34,DVB-S,QPSK
+8=3732,V,2222,Auto,DVB-S,QPSK
+9=3734,V,2852,34,DVB-S,QPSK
+10=3736,H,1808,34,DVB-S,QPSK
+11=3736,V,2853,34,DVB-S,QPSK
+12=3744,H,2110,Auto,DVB-S,QPSK
+13=3762,H,2222,78,DVB-S,QPSK
+14=3766,H,3336,34,DVB-S,QPSK
+15=3771,V,1480,34,DVB-S,QPSK
+16=3774,V,2222,34,DVB-S,QPSK
+17=3792,V,3393,34,DVB-S,QPSK
+18=3800,H,30000,56,S2,8PSK
+19=3832,H,4800,56,DVB-S,QPSK
+20=3850,H,6666,Auto,DVB-S,QPSK
+21=3853,H,2170,78,DVB-S,QPSK
+22=3864,H,3333,34,DVB-S,QPSK
+23=3876,V,2740,34,DVB-S,QPSK
+24=3894,H,6666,Auto,DVB-S,QPSK
+25=3920,H,27500,78,DVB-S,QPSK
+26=3926,V,7072,34,S2,8PSK
+27=3935,V,7072,23,S2,8PSK
+28=3943,V,8500,34,S2,8PSK
+29=3950,V,3200,23,S2,8PSK
+30=3968,V,7500,Auto,S2,8PSK
+31=3975,V,4167,34,S2,QPSK
+32=4014,H,3750,Auto,S2,8PSK
+33=4017,H,2083,34,S2,8PSK
+34=4046,V,4000,56,DVB-S,QPSK
+35=4051,V,5416,23,S2,8PSK
+36=4100,V,30000,56,S2,8PSK
+37=4121,H,4800,34,DVB-S,QPSK
+38=4130,H,1850,23,DVB-S,QPSK
+39=4140,V,30000,56,S2,8PSK
+40=11885,H,2000,12,S2,QPSK
+41=11893,H,2034,Auto,DVB-S,QPSK
+42=11930,H,14400,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini
new file mode 100644
index 000000000..60e1423fd
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2970.ini
@@ -0,0 +1,27 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2970
+2=Telstar 14R (63.0W)
+
+[DVB]
+0=18
+1=11600,V,13744,Auto,DVB-S,QPSK
+2=11640,V,18100,78,DVB-S,QPSK
+3=11706,V,2278,34,S2,QPSK
+4=11710,V,3200,23,DVB-S,QPSK
+5=11722,V,2963,34,DVB-S,QPSK
+6=11726,V,3333,34,DVB-S,QPSK
+7=11732,V,2222,Auto,DVB-S,QPSK
+8=11736,V,2963,34,DVB-S,QPSK
+9=11795,V,4444,Auto,DVB-S,QPSK
+10=11805,V,6666,Auto,DVB-S,QPSK
+11=11827,V,3200,Auto,DVB-S,QPSK
+12=11844,V,5348,Auto,DVB-S,QPSK
+13=11850,V,2280,34,DVB-S,QPSK
+14=11871,V,2000,34,DVB-S,QPSK
+15=11888,V,3330,34,DVB-S,QPSK
+16=11905,V,2362,34,DVB-S,QPSK
+17=11958,H,3255,Auto,DVB-S,QPSK
+18=12162,H,13021,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini
new file mode 100644
index 000000000..1dc03e67f
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2985.ini
@@ -0,0 +1,41 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2985
+2=EchoStar 12/16 (61.5W)
+
+[DVB]
+0=32
+1=12224,V,20000,78,DVB-S,QPSK
+2=12239,H,21500,23,DVB-S,8PSK
+3=12253,V,21500,23,DVB-S,8PSK
+4=12268,H,21500,23,DVB-S,8PSK
+5=12282,V,21500,23,DVB-S,8PSK
+6=12297,H,21500,23,DVB-S,8PSK
+7=12311,V,21500,23,DVB-S,8PSK
+8=12326,H,21500,23,DVB-S,8PSK
+9=12341,V,21500,23,DVB-S,8PSK
+10=12355,H,21500,23,DVB-S,8PSK
+11=12370,V,21500,23,DVB-S,8PSK
+12=12384,H,21500,23,DVB-S,8PSK
+13=12399,V,21500,23,DVB-S,8PSK
+14=12414,H,20000,78,DVB-S,QPSK
+15=12428,V,21500,23,DVB-S,8PSK
+16=12443,H,21500,23,DVB-S,8PSK
+17=12457,V,21500,23,DVB-S,8PSK
+18=12472,H,21500,34,DVB-S,8PSK
+19=12486,V,21500,34,DVB-S,8PSK
+20=12501,H,21500,34,DVB-S,8PSK
+21=12516,V,21500,34,DVB-S,8PSK
+22=12530,H,21500,34,DVB-S,8PSK
+23=12545,V,21500,34,DVB-S,8PSK
+24=12559,H,21500,34,DVB-S,8PSK
+25=12574,V,21500,34,DVB-S,8PSK
+26=12588,H,21500,34,DVB-S,8PSK
+27=12603,V,21500,34,DVB-S,8PSK
+28=12618,H,21500,34,DVB-S,8PSK
+29=12632,V,21500,34,DVB-S,8PSK
+30=12647,H,21500,34,DVB-S,8PSK
+31=12661,V,21500,34,DVB-S,8PSK
+32=12676,H,21500,34,DVB-S,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini
new file mode 100644
index 000000000..ce35c62f5
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/2990.ini
@@ -0,0 +1,67 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=2990
+2=Amazonas 2/3/4A (61.0W)
+
+[DVB]
+0=58
+1=3630,H,2785,34,DVB-S,QPSK
+2=3659,H,6666,Auto,DVB-S,QPSK
+3=3668,H,6666,Auto,DVB-S,QPSK
+4=3767,H,1600,34,S2,QPSK
+5=3925,V,3333,34,DVB-S,QPSK
+6=3927,V,2222,34,DVB-S,QPSK
+7=3941,V,3480,34,DVB-S,QPSK
+8=3948,H,4440,Auto,DVB-S,QPSK
+9=3958,H,4440,Auto,DVB-S,QPSK
+10=3967,H,6670,Auto,DVB-S,QPSK
+11=3990,H,2142,34,DVB-S,QPSK
+12=3996,H,7501,23,S2,8PSK
+13=4139,H,4543,34,S2,QPSK
+14=4142,V,2651,34,DVB-S,QPSK
+15=4148,H,5384,35,S2,8PSK
+16=4156,H,2813,Auto,DVB-S,QPSK
+17=4160,V,2500,34,S2,QPSK
+18=4164,H,3846,34,DVB-S,QPSK
+19=4168,H,3461,34,DVB-S,QPSK
+20=10728,H,28888,34,DVB-S,QPSK
+21=10728,V,30000,34,S2,8PSK
+22=10768,H,28888,34,DVB-S,QPSK
+23=10768,V,30000,23,S2,8PSK
+24=10808,H,30000,23,S2,8PSK
+25=10848,H,30000,23,S2,8PSK
+26=10888,V,28888,34,DVB-S,QPSK
+27=10928,H,28888,34,DVB-S,QPSK
+28=11015,H,28880,34,DVB-S,QPSK
+29=11026,V,10805,23,S2,8PSK
+30=11055,H,28880,34,DVB-S,QPSK
+31=11095,H,28880,34,DVB-S,QPSK
+32=11095,V,30000,23,S2,8PSK
+33=11135,H,28880,34,DVB-S,QPSK
+34=11135,V,28880,Auto,DVB-S,QPSK
+35=11175,H,28888,34,DVB-S,QPSK
+36=11222,H,28888,34,DVB-S,QPSK
+37=11222,V,30000,23,S2,8PSK
+38=11262,H,30000,23,S2,8PSK
+39=11262,V,30000,23,S2,8PSK
+40=11302,H,28888,34,DVB-S,QPSK
+41=11342,H,28888,34,DVB-S,QPSK
+42=11342,V,30000,23,S2,8PSK
+43=11382,H,28888,34,DVB-S,QPSK
+44=11422,H,28888,34,DVB-S,QPSK
+45=11738,V,40000,23,DVB-S,QPSK
+46=11851,H,28880,Auto,DVB-S,QPSK
+47=11885,H,15000,23,S2,8PSK
+48=11932,H,28888,23,DVB-S,QPSK
+49=11972,V,30000,34,DVB-S,QPSK
+50=11972,H,28888,34,DVB-S,QPSK
+51=12012,H,28888,34,DVB-S,QPSK
+52=12052,H,28888,34,DVB-S,QPSK
+53=12060,V,18000,Auto,DVB-S,QPSK
+54=12092,V,30000,23,DVB-S,QPSK
+55=12092,H,28880,34,DVB-S,QPSK
+56=12132,H,30000,23,S2,8PSK
+57=12172,V,30000,23,DVB-S,QPSK
+58=12172,H,30000,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini
new file mode 100644
index 000000000..3b6673b47
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3020.ini
@@ -0,0 +1,67 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3020
+2=Intelsat 21 (58.0W)
+
+[DVB]
+0=58
+1=3720,V,30000,89,S2,8PSK
+2=3720,H,27000,34,S2,8PSK
+3=3760,V,27690,78,DVB-S,QPSK
+4=3760,H,30000,56,S2,8PSK
+5=3785,H,5200,910,S2,QPSK
+6=3791,H,3330,34,DVB-S,QPSK
+7=3797,H,2218,34,DVB-S,QPSK
+8=3805,H,3147,34,DVB-S,QPSK
+9=3840,V,27690,78,DVB-S,QPSK
+10=3840,H,27690,78,DVB-S,QPSK
+11=3880,V,30000,34,S2,8PSK
+12=3880,H,27690,78,DVB-S,QPSK
+13=3910,V,15000,23,S2,8PSK
+14=3920,H,27690,78,S2,QPSK
+15=3924,V,6620,34,DVB-S,QPSK
+16=3933,V,7000,34,DVB-S,QPSK
+17=3952,H,15145,23,S2,8PSK
+18=3960,V,30000,34,S2,8PSK
+19=3972,H,9850,56,S2,QPSK
+20=4000,H,28120,56,S2,8PSK
+21=4040,V,30000,56,S2,8PSK
+22=4040,H,26590,12,DVB-S,QPSK
+23=4080,V,27690,56,DVB-S,QPSK
+24=4080,H,30000,56,S2,8PSK
+25=4107,H,9850,34,DVB-S,QPSK
+26=4120,V,27500,34,DVB-S,QPSK
+27=4122,H,2222,34,DVB-S,QPSK
+28=4126,H,3700,34,DVB-S,QPSK
+29=4137,H,2020,56,DVB-S,QPSK
+30=4144,V,2205,34,DVB-S,QPSK
+31=4147,H,6111,34,S2,QPSK
+32=4151,V,3000,78,DVB-S,QPSK
+33=4155,H,5632,34,DVB-S,QPSK
+34=4156,V,4300,56,DVB-S,QPSK
+35=4160,V,2941,34,DVB-S,QPSK
+36=4166,H,5632,34,DVB-S,QPSK
+37=4169,V,3000,34,DVB-S,QPSK
+38=4174,V,2941,34,DVB-S,QPSK
+39=4175,H,6620,34,DVB-S,QPSK
+40=11648,V,2520,Auto,DVB-S,QPSK
+41=11693,V,2970,Auto,DVB-S,QPSK
+42=11720,H,30000,35,S2,8PSK
+43=11740,V,30000,35,S2,8PSK
+44=11840,H,30000,56,DVB-S,QPSK
+45=11860,V,30000,35,S2,8PSK
+46=11960,H,30000,Auto,DVB-S,QPSK
+47=11980,V,30000,Auto,DVB-S,QPSK
+48=12000,H,30000,Auto,DVB-S,QPSK
+49=12020,V,30000,Auto,DVB-S,QPSK
+50=12040,H,30000,Auto,DVB-S,QPSK
+51=12060,V,30000,Auto,DVB-S,QPSK
+52=12067,V,2522,23,DVB-S,QPSK
+53=12080,H,30000,Auto,DVB-S,QPSK
+54=12100,V,30000,Auto,DVB-S,QPSK
+55=12120,H,30000,Auto,DVB-S,QPSK
+56=12140,V,30000,Auto,DVB-S,QPSK
+57=12160,H,30000,Auto,DVB-S,QPSK
+58=12180,V,30000,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini
new file mode 100644
index 000000000..1d462c1a8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3045.ini
@@ -0,0 +1,107 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3045
+2=Amazonas 1/Galaxy 11/Intelsat 805 (55.5W)
+
+[DVB]
+0=98
+1=3478,V,5632,34,DVB-S,QPSK
+2=3670,H,1374,34,DVB-S,QPSK
+3=3675,V,7120,34,S2,8PSK
+4=3678,H,2960,34,DVB-S,QPSK
+5=3682,V,3333,34,DVB-S,QPSK
+6=3687,V,3333,34,DVB-S,QPSK
+7=3688,H,3320,34,DVB-S,QPSK
+8=3693,H,3320,34,DVB-S,QPSK
+9=3715,H,8890,34,DVB-S,QPSK
+10=3719,V,1950,Auto,S2,8PSK
+11=3727,V,3333,34,DVB-S,QPSK
+12=3735,V,8681,34,DVB-S,QPSK
+13=3740,H,1205,23,DVB-S,QPSK
+14=3743,H,2500,34,S2,8PSK
+15=3747,H,1600,35,S2,QPSK
+16=3750,V,3750,Auto,S2,8PSK
+17=3754,H,4232,34,DVB-S,QPSK
+18=3759,V,18400,23,S2,8PSK
+19=3759,H,2963,34,DVB-S,QPSK
+20=3763,H,3000,34,S2,QPSK
+21=3768,H,4427,23,DVB-S,QPSK
+22=3776,H,7996,35,S2,8PSK
+23=3791,V,3255,Auto,DVB-S,QPSK
+24=3794,H,1600,23,S2,QPSK
+25=3808,V,26666,78,DVB-S,QPSK
+26=3816,H,26666,34,DVB-S,QPSK
+27=3823,V,4430,34,DVB-S,QPSK
+28=3836,H,2500,34,S2,QPSK
+29=3839,H,2600,89,S2,QPSK
+30=3842,H,2580,34,DVB-S,QPSK
+31=3845,V,26700,34,DVB-S,QPSK
+32=3849,H,1600,23,S2,8PSK
+33=3855,H,2220,Auto,S2,8PSK
+34=3859,H,3330,56,S2,8PSK
+35=3872,H,9333,35,S2,8PSK
+36=3890,H,3333,56,DVB-S,QPSK
+37=3894,H,3617,34,DVB-S,QPSK
+38=3910,H,5832,56,S2,QPSK
+39=3915,H,3300,34,DVB-S,QPSK
+40=3924,H,7200,34,S2,8PSK
+41=3930,H,3255,23,DVB-S,QPSK
+42=3936,H,3255,23,DVB-S,QPSK
+43=3963,V,3330,34,DVB-S,QPSK
+44=3965,H,7120,34,S2,8PSK
+45=3966,V,2963,34,DVB-S,QPSK
+46=3970,V,3702,23,DVB-S,QPSK
+47=3972,H,6920,34,S2,8PSK
+48=3978,H,3200,34,DVB-S,QPSK
+49=3982,H,4440,34,DVB-S,QPSK
+50=3987,V,3330,34,S2,8PSK
+51=3990,V,3590,23,S2,8PSK
+52=3991,H,6666,34,DVB-S,QPSK
+53=4003,V,8681,34,DVB-S,QPSK
+54=4011,V,3330,23,S2,8PSK
+55=4015,H,30000,23,S2,8PSK
+56=4023,V,4289,Auto,DVB-S,QPSK
+57=4028,V,4410,34,DVB-S,QPSK
+58=4042,H,7120,34,DVB-S,QPSK
+59=4052,V,3125,34,DVB-S,QPSK
+60=4056,H,3320,34,DVB-S,QPSK
+61=4067,V,4440,34,DVB-S,QPSK
+62=4070,H,7120,34,S2,8PSK
+63=4080,V,4400,56,DVB-S,QPSK
+64=4084,H,10560,35,S2,8PSK
+65=4086,V,4074,56,S2,QPSK
+66=4093,V,3617,34,DVB-S,QPSK
+67=4093,H,3040,35,S2,8PSK
+68=4096,H,1300,35,S2,8PSK
+69=4097,V,3700,78,DVB-S,QPSK
+70=4098,H,2272,56,S2,QPSK
+71=4100,H,1840,35,S2,8PSK
+72=4101,V,2320,89,S2,QPSK
+73=4106,H,5360,35,S2,8PSK
+74=4107,V,2960,34,DVB-S,QPSK
+75=4111,V,1850,23,S2,8PSK
+76=4111,H,4000,35,S2,8PSK
+77=4127,H,2961,34,DVB-S,QPSK
+78=4134,H,4444,34,DVB-S,QPSK
+79=4136,V,30000,56,S2,8PSK
+80=4137,H,2000,34,DVB-S,8PSK
+81=4142,H,5000,34,S2,8PSK
+82=4147,H,3444,34,DVB-S,QPSK
+83=4151,H,2500,34,DVB-S,QPSK
+84=4160,H,5600,23,S2,8PSK
+85=4170,H,6111,Auto,DVB-S,QPSK
+86=4177,V,30000,56,S2,8PSK
+87=4193,H,4444,34,S2,QPSK
+88=10976,H,22000,34,S2,8PSK
+89=11006,H,23300,34,S2,8PSK
+90=11024,V,23300,34,S2,8PSK
+91=11036,H,23300,34,S2,8PSK
+92=11054,V,23300,34,S2,8PSK
+93=11066,H,23300,34,S2,8PSK
+94=11096,H,23300,34,S2,8PSK
+95=11126,H,23300,34,S2,8PSK
+96=11156,H,23300,34,S2,8PSK
+97=11186,H,23300,34,S2,8PSK
+98=11921,V,39200,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini
new file mode 100644
index 000000000..16baee6ce
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3070.ini
@@ -0,0 +1,24 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3070
+2=Intelsat 23 (53.0W)
+
+[DVB]
+0=15
+1=3715,V,2500,34,S2,QPSK
+2=3720,V,3906,12,DVB-S,QPSK
+3=3820,V,3255,Auto,DVB-S,QPSK
+4=3882,V,18808,34,DVB-S,QPSK
+5=3932,V,4340,Auto,DVB-S,QPSK
+6=3998,H,4445,12,DVB-S,QPSK
+7=4004,H,4445,12,DVB-S,QPSK
+8=4009,H,2963,34,DVB-S,QPSK
+9=4012,H,2963,34,DVB-S,QPSK
+10=4016,H,2963,34,DVB-S,QPSK
+11=4028,H,2963,34,DVB-S,QPSK
+12=4119,V,6666,34,DVB-S,QPSK
+13=4135,H,4300,78,DVB-S,QPSK
+14=11911,V,2821,34,DVB-S,QPSK
+15=12138,H,3111,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini
new file mode 100644
index 000000000..2155127dc
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3100.ini
@@ -0,0 +1,43 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3100
+2=Intelsat 1R (50.0W)
+
+[DVB]
+0=34
+1=3743,V,7200,Auto,S2,QPSK
+2=3760,V,2410,Auto,DVB-S,QPSK
+3=3765,V,2410,12,DVB-S,QPSK
+4=3778,V,5184,Auto,DVB-S,QPSK
+5=3784,V,2240,Auto,DVB-S,QPSK
+6=3792,V,2222,Auto,DVB-S,QPSK
+7=4094,H,2963,34,DVB-S,QPSK
+8=4098,H,2963,34,DVB-S,QPSK
+9=4102,H,2963,34,DVB-S,QPSK
+10=4106,H,2963,34,DVB-S,QPSK
+11=4111,H,2963,34,DVB-S,QPSK
+12=4125,V,10713,34,DVB-S,QPSK
+13=4135,V,3382,34,DVB-S,QPSK
+14=4141,V,5384,35,DVB-S,QPSK
+15=4149,V,6153,Auto,DVB-S,QPSK
+16=4182,V,7600,12,S2,8PSK
+17=11050,V,27902,34,S2,QPSK
+18=11090,V,27902,34,S2,QPSK
+19=11130,V,27902,34,S2,QPSK
+20=11170,V,27902,34,S2,QPSK
+21=11455,V,4440,Auto,DVB-S,QPSK
+22=11464,V,3320,Auto,DVB-S,QPSK
+23=11469,V,3320,Auto,DVB-S,QPSK
+24=11473,V,3320,Auto,DVB-S,QPSK
+25=11478,V,3320,Auto,DVB-S,QPSK
+26=11483,V,3320,Auto,DVB-S,QPSK
+27=11787,H,3330,Auto,DVB-S,QPSK
+28=11789,V,10000,Auto,DVB-S,QPSK
+29=11797,H,6500,Auto,DVB-S,QPSK
+30=11804,H,6500,Auto,DVB-S,QPSK
+31=11804,V,4440,Auto,DVB-S,QPSK
+32=11813,H,6500,Auto,DVB-S,QPSK
+33=11816,V,2960,Auto,DVB-S,QPSK
+34=11825,H,4500,Auto,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini
new file mode 100644
index 000000000..07c07c7ff
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3125.ini
@@ -0,0 +1,17 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3125
+2=NSS 806 (47.5W)
+
+[DVB]
+0=8
+1=3725,H,30000,34,S2,8PSK
+2=3803,V,28000,34,S2,8PSK
+3=4002,V,7200,34,S2,QPSK
+4=4015,H,30000,23,S2,8PSK
+5=4055,V,30000,56,S2,8PSK
+6=4135,V,28000,34,S2,8PSK
+7=4163,V,9247,56,S2,QPSK
+8=4178,H,30000,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini
new file mode 100644
index 000000000..e322e36f8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3150.ini
@@ -0,0 +1,33 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3150
+2=Intelsat 14 (45.0W)
+
+[DVB]
+0=24
+1=3759,V,4412,34,DVB-S,QPSK
+2=3766,V,3255,34,DVB-S,QPSK
+3=3769,V,2400,34,DVB-S,QPSK
+4=3777,V,2400,56,DVB-S,QPSK
+5=3780,V,2941,34,DVB-S,QPSK
+6=3789,V,1667,Auto,S2,QPSK
+7=3844,V,2222,Auto,DVB-S,QPSK
+8=3853,V,11029,78,DVB-S,QPSK
+9=3866,V,10073,78,DVB-S,QPSK
+10=3913,H,2482,23,S2,QPSK
+11=3968,V,3600,Auto,DVB-S,QPSK
+12=3986,V,4411,56,DVB-S,QPSK
+13=4072,V,2068,56,DVB-S,QPSK
+14=4110,H,4444,34,DVB-S,QPSK
+15=4165,V,4412,56,DVB-S,QPSK
+16=4171,V,3309,34,DVB-S,QPSK
+17=4176,V,3888,Auto,DVB-S,QPSK
+18=4186,H,4960,35,S2,QPSK
+19=4192,H,2075,34,DVB-S,QPSK
+20=4192,V,1600,35,S2,8PSK
+21=11600,V,1000,34,DVB-S,QPSK
+22=11608,H,1852,56,DVB-S,QPSK
+23=11638,H,5632,34,DVB-S,QPSK
+24=11647,H,6620,23,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini
new file mode 100644
index 000000000..8ed74f2ef
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3169.ini
@@ -0,0 +1,76 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3169
+2=Intelsat 11 (43.1W)
+
+[DVB]
+0=67
+1=3717,H,22000,56,S2,8PSK
+2=3718,V,21600,56,S2,8PSK
+3=3736,H,29270,78,DVB-S,QPSK
+4=3745,V,21610,34,S2,8PSK
+5=3780,H,27690,78,DVB-S,QPSK
+6=3783,V,30000,56,S2,8PSK
+7=3808,V,15000,56,S2,8PSK
+8=3808,H,14950,56,S2,8PSK
+9=3825,H,7500,34,S2,QPSK
+10=3828,V,3300,34,DVB-S,QPSK
+11=3834,H,3200,35,S2,8PSK
+12=3836,V,7780,23,S2,8PSK
+13=3838,H,3600,34,DVB-S,QPSK
+14=3844,H,3600,34,DVB-S,QPSK
+15=3845,V,7700,34,S2,QPSK
+16=3850,H,7500,23,S2,8PSK
+17=3854,V,5945,34,DVB-S,QPSK
+18=3864,V,7120,34,S2,8PSK
+19=3868,H,13600,34,S2,8PSK
+20=3871,V,2500,34,S2,8PSK
+21=3874,V,2421,34,S2,8PSK
+22=3875,H,3750,35,S2,8PSK
+23=3877,V,1546,23,DVB-S,QPSK
+24=3888,H,7200,34,S2,8PSK
+25=3895,V,17405,34,DVB-S,QPSK
+26=3927,V,30000,56,DVB-S,QPSK
+27=3928,H,14060,34,S2,8PSK
+28=3945,H,6250,34,S2,8PSK
+29=3963,V,13400,56,DVB-S,QPSK
+30=3966,H,21090,34,DVB-S,QPSK
+31=3975,V,3590,56,S2,8PSK
+32=3984,V,9760,34,DVB-S,QPSK
+33=3992,V,7320,23,DVB-S,QPSK
+34=3994,H,21090,34,DVB-S,QPSK
+35=4012,V,6650,Auto,DVB-S,QPSK
+36=4026,V,16900,78,DVB-S,QPSK
+37=4040,H,30800,78,DVB-S,QPSK
+38=4048,V,20832,34,S2,8PSK
+39=4074,V,2500,56,S2,8PSK
+40=4079,V,4400,34,DVB-S,QPSK
+41=4113,H,19510,Auto,DVB-S,QPSK
+42=4115,V,19580,34,S2,8PSK
+43=4135,V,2222,34,DVB-S,QPSK
+44=4140,H,9600,34,S2,8PSK
+45=4149,V,20083,23,S2,8PSK
+46=4150,H,7500,23,S2,8PSK
+47=4168,H,4800,Auto,S2,8PSK
+48=4185,H,7120,34,S2,8PSK
+49=4193,H,6620,34,S2,QPSK
+50=10722,V,30000,34,DVB-S,QPSK
+51=10722,H,30000,34,DVB-S,QPSK
+52=10802,V,30000,34,DVB-S,QPSK
+53=10802,H,28000,Auto,DVB-S,QPSK
+54=10882,V,30000,34,DVB-S,QPSK
+55=10882,H,30000,34,DVB-S,QPSK
+56=10970,V,28000,Auto,DVB-S,QPSK
+57=10970,H,29000,34,DVB-S,QPSK
+58=11050,V,29000,Auto,DVB-S,QPSK
+59=11050,H,29000,Auto,DVB-S,QPSK
+60=11130,V,29000,34,DVB-S,QPSK
+61=11130,H,28000,Auto,DVB-S,QPSK
+62=11222,V,30000,23,S2,8PSK
+63=11222,H,30000,23,S2,8PSK
+64=11302,V,30000,23,S2,8PSK
+65=11302,H,30000,23,S2,8PSK
+66=11382,V,30000,34,DVB-S,QPSK
+67=11382,H,30000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini
new file mode 100644
index 000000000..b331b7d64
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3195.ini
@@ -0,0 +1,151 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3195
+2=SES 6 (40.5W)
+
+[DVB]
+0=142
+1=3626,H,2800,34,S2,8PSK
+2=3628,V,2170,34,DVB-S,QPSK
+3=3630,H,2222,34,DVB-S,QPSK
+4=3633,H,1480,56,S2,8PSK
+5=3634,V,2712,34,DVB-S,QPSK
+6=3637,H,1855,34,DVB-S,QPSK
+7=3641,V,2666,34,DVB-S,QPSK
+8=3641,H,2788,Auto,S2,8PSK
+9=3644,H,2532,34,DVB-S,QPSK
+10=3646,V,6666,34,DVB-S,QPSK
+11=3648,H,2068,23,S2,8PSK
+12=3652,H,4000,56,DVB-S,QPSK
+13=3658,H,1666,56,S2,8PSK
+14=3658,V,4800,89,S2,QPSK
+15=3666,V,2222,56,DVB-S,QPSK
+16=3668,H,2170,34,DVB-S,QPSK
+17=3673,V,4700,56,S2,8PSK
+18=3673,H,4350,34,DVB-S,QPSK
+19=3677,H,2000,23,S2,8PSK
+20=3682,H,3333,34,DVB-S,QPSK
+21=3684,V,3750,34,S2,8PSK
+22=3688,V,3650,34,DVB-S,QPSK
+23=3691,H,2740,23,DVB-S,QPSK
+24=3694,V,5180,34,DVB-S,QPSK
+25=3695,H,2963,34,DVB-S,QPSK
+26=3699,V,2200,34,DVB-S,QPSK
+27=3710,H,7400,78,DVB-S,QPSK
+28=3725,H,10000,56,S2,8PSK
+29=3732,V,8156,56,DVB-S,QPSK
+30=3735,H,7400,78,DVB-S,QPSK
+31=3758,H,18500,78,DVB-S,QPSK
+32=3763,V,30000,56,S2,8PSK
+33=3803,V,26860,78,DVB-S,QPSK
+34=3803,H,27500,78,DVB-S,QPSK
+35=3830,V,6142,78,DVB-S,QPSK
+36=3835,V,2082,34,S2,8PSK
+37=3843,H,30000,89,S2,8PSK
+38=3848,V,2800,34,DVB-S,QPSK
+39=3856,V,8370,34,S2,8PSK
+40=3866,H,2222,78,DVB-S,QPSK
+41=3870,H,3750,56,S2,8PSK
+42=3875,H,3867,34,S2,QPSK
+43=3883,V,26660,56,DVB-S,QPSK
+44=3883,H,1837,34,S2,8PSK
+45=3886,H,2617,34,S2,8PSK
+46=3888,H,1050,56,S2,8PSK
+47=3893,H,2217,78,DVB-S,QPSK
+48=3897,H,2000,34,S2,8PSK
+49=3899,H,1900,34,DVB-S,QPSK
+50=3907,H,2548,34,S2,8PSK
+51=3909,H,2455,34,S2,8PSK
+52=3915,H,5830,23,S2,8PSK
+53=3920,V,20000,35,S2,QPSK
+54=3935,H,8880,34,DVB-S,QPSK
+55=3937,V,2170,34,DVB-S,QPSK
+56=3960,V,1259,78,DVB-S,QPSK
+57=3964,V,2000,56,S2,8PSK
+58=3966,V,1920,23,S2,8PSK
+59=3980,V,17800,34,DVB-S,QPSK
+60=3980,H,21600,34,S2,8PSK
+61=3990,V,4195,34,DVB-S,QPSK
+62=3998,H,1630,34,S2,8PSK
+63=4000,H,1600,34,S2,8PSK
+64=4002,H,1570,34,S2,8PSK
+65=4004,H,1530,34,S2,8PSK
+66=4006,H,1500,34,S2,8PSK
+67=4008,H,1470,34,S2,8PSK
+68=4013,H,6600,34,S2,8PSK
+69=4021,V,3200,34,S2,8PSK
+70=4025,H,12832,34,S2,8PSK
+71=4028,V,8000,34,S2,8PSK
+72=4047,H,3330,78,DVB-S,QPSK
+73=4054,H,6666,34,DVB-S,QPSK
+74=4056,V,3000,23,DVB-S,QPSK
+75=4063,H,7000,56,S2,8PSK
+76=4065,V,12500,34,DVB-S,QPSK
+77=4070,H,4440,78,DVB-S,QPSK
+78=4080,H,4937,Auto,DVB-S,QPSK
+79=4081,V,6511,56,DVB-S,QPSK
+80=4086,V,1476,78,DVB-S,QPSK
+81=4092,H,1600,56,S2,QPSK
+82=4092,V,1150,34,DVB-S,QPSK
+83=4100,V,6111,34,DVB-S,QPSK
+84=4111,V,2000,56,DVB-S,QPSK
+85=4119,V,2960,34,DVB-S,QPSK
+86=4121,H,2400,34,S2,8PSK
+87=4124,V,4196,34,DVB-S,QPSK
+88=4125,H,3625,56,S2,8PSK
+89=4130,V,3844,78,DVB-S,QPSK
+90=4132,H,2480,34,DVB-S,QPSK
+91=4136,V,3000,56,S2,8PSK
+92=4137,H,4400,34,DVB-S,QPSK
+93=4140,V,2220,78,DVB-S,QPSK
+94=4142,V,1030,78,DVB-S,QPSK
+95=4142,H,2222,78,DVB-S,QPSK
+96=4144,V,2800,34,S2,8PSK
+97=4146,H,2571,78,DVB-S,QPSK
+98=4151,V,3280,56,DVB-S,QPSK
+99=4161,H,6510,34,DVB-S,QPSK
+100=4168,H,2400,23,DVB-S,QPSK
+101=4168,V,18392,23,S2,8PSK
+102=4170,H,2222,34,DVB-S,QPSK
+103=4175,H,3350,23,S2,8PSK
+104=4179,H,3332,23,S2,8PSK
+105=4187,V,11500,34,DVB-S,QPSK
+106=4196,V,2960,56,DVB-S,QPSK
+107=11480,V,30000,12,S2,8PSK
+108=11480,H,30000,34,S2,8PSK
+109=11520,V,30000,34,S2,8PSK
+110=11520,H,30000,34,S2,8PSK
+111=11560,V,30000,23,S2,8PSK
+112=11560,H,30000,34,S2,8PSK
+113=11600,H,30000,34,S2,8PSK
+114=11600,V,30000,34,S2,8PSK
+115=11640,H,30000,34,S2,8PSK
+116=11640,V,30000,34,S2,8PSK
+117=11680,H,30000,34,S2,8PSK
+118=11680,V,30000,34,S2,8PSK
+119=11736,V,22500,34,S2,8PSK
+120=11764,V,22500,34,S2,8PSK
+121=11796,V,22500,34,S2,8PSK
+122=11824,V,22500,34,S2,8PSK
+123=11856,V,22500,34,S2,8PSK
+124=11884,V,22500,34,S2,8PSK
+125=11916,V,22500,34,S2,8PSK
+126=11944,V,22500,34,S2,8PSK
+127=11976,V,22500,34,S2,8PSK
+128=11976,H,22500,34,S2,8PSK
+129=12004,V,22500,34,S2,8PSK
+130=12004,H,22500,34,S2,8PSK
+131=12036,H,22500,34,S2,8PSK
+132=12036,V,22500,34,S2,8PSK
+133=12064,H,22500,34,S2,8PSK
+134=12064,V,22500,34,S2,8PSK
+135=12096,H,22500,34,S2,8PSK
+136=12096,V,22500,34,S2,8PSK
+137=12124,H,22500,34,S2,8PSK
+138=12124,V,22500,34,S2,8PSK
+139=12156,H,22500,34,S2,8PSK
+140=12156,V,22500,34,S2,8PSK
+141=12184,H,22500,34,S2,8PSK
+142=12184,V,22500,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini
new file mode 100644
index 000000000..800e74334
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3225.ini
@@ -0,0 +1,62 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3225
+2=NSS 10/Telstar 11N (37.5W)
+
+[DVB]
+0=53
+1=3746,V,1229,56,S2,QPSK
+2=3746,H,1229,56,S2,QPSK
+3=3749,V,1674,78,DVB-S,QPSK
+4=3749,H,1674,78,DVB-S,QPSK
+5=3756,V,1777,34,S2,8PSK
+6=3756,H,1777,34,S2,8PSK
+7=3833,H,2893,34,DVB-S,QPSK
+8=3868,V,6666,34,DVB-S,QPSK
+9=3888,H,3250,34,DVB-S,QPSK
+10=3929,H,8882,34,DVB-S,QPSK
+11=4044,V,3250,34,DVB-S,QPSK
+12=4055,V,2700,56,DVB-S,QPSK
+13=4059,V,3214,56,DVB-S,QPSK
+14=4066,V,2893,34,DVB-S,QPSK
+15=4068,V,2540,78,DVB-S,QPSK
+16=4072,V,3150,34,DVB-S,QPSK
+17=4083,H,10000,23,S2,8PSK
+18=4172,H,8888,Auto,DVB-S,QPSK
+19=4177,V,23500,12,S2,QPSK
+20=10965,V,3300,56,DVB-S,QPSK
+21=10970,V,1847,56,S2,QPSK
+22=10975,H,3250,Auto,S2,QPSK
+23=10975,V,2894,34,S2,8PSK
+24=10978,H,3124,34,DVB-S,QPSK
+25=10979,V,2894,34,S2,8PSK
+26=10982,V,1000,Auto,S2,QPSK
+27=10989,V,5632,34,DVB-S,QPSK
+28=10991,H,6111,34,DVB-S,QPSK
+29=10994,V,4800,34,S2,8PSK
+30=11001,V,4280,34,DVB-S,QPSK
+31=11032,V,6111,34,DVB-S,QPSK
+32=11043,V,6666,78,DVB-S,QPSK
+33=11482,H,11970,56,DVB-S,QPSK
+34=11637,V,3885,34,S2,8PSK
+35=11679,V,4090,34,S2,8PSK
+36=11839,V,3125,Auto,DVB-S,QPSK
+37=11875,V,5632,Auto,DVB-S,QPSK
+38=12504,V,3400,78,DVB-S,QPSK
+39=12515,H,3460,78,DVB-S,QPSK
+40=12517,V,10800,Auto,S2,QPSK
+41=12524,V,3600,Auto,DVB-S,QPSK
+42=12533,V,6111,34,DVB-S,QPSK
+43=12542,V,6111,34,DVB-S,QPSK
+44=12543,V,3500,34,DVB-S,QPSK
+45=12551,V,6111,34,DVB-S,QPSK
+46=12584,V,6111,34,DVB-S,QPSK
+47=12595,V,6650,34,DVB-S,QPSK
+48=12606,V,9600,34,S2,8PSK
+49=12615,V,3124,34,DVB-S,QPSK
+50=12674,V,7500,56,S2,8PSK
+51=12690,V,7500,56,S2,8PSK
+52=12708,V,7200,23,S2,8PSK
+53=12717,V,6620,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini
new file mode 100644
index 000000000..eb56de14b
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3255.ini
@@ -0,0 +1,42 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3255
+2=Intelsat 903 (34.5W)
+
+[DVB]
+0=33
+1=3658,V,3300,34,DVB-S,QPSK
+2=3676,V,3220,34,DVB-S,QPSK
+3=4045,H,13500,23,S2,QPSK
+4=4095,V,30000,34,S2,QPSK
+5=4126,H,3680,23,DVB-S,QPSK
+6=10960,V,5632,34,DVB-S,QPSK
+7=10968,V,5632,34,DVB-S,QPSK
+8=10977,V,5632,34,DVB-S,QPSK
+9=10986,V,5632,34,DVB-S,QPSK
+10=10993,V,7200,34,S2,QPSK
+11=10995,H,44950,56,S2,QPSK
+12=11028,V,5000,23,S2,8PSK
+13=11049,V,13333,78,DVB-S,QPSK
+14=11075,H,45000,34,S2,QPSK
+15=11088,V,20640,56,S2,8PSK
+16=11106,V,7750,23,S2,8PSK
+17=11190,H,3333,Auto,DVB-S,QPSK
+18=11495,H,45000,34,S2,QPSK
+19=11555,H,30000,89,S2,QPSK
+20=11568,V,6111,34,DVB-S,QPSK
+21=11580,V,6220,56,DVB-S,QPSK
+22=11589,V,6220,56,DVB-S,QPSK
+23=11596,H,30000,89,S2,QPSK
+24=11598,V,6220,56,DVB-S,QPSK
+25=11604,V,4280,34,DVB-S,QPSK
+26=11610,V,6111,34,DVB-S,QPSK
+27=11620,V,4224,78,DVB-S,QPSK
+28=11625,V,4224,78,DVB-S,QPSK
+29=11631,V,4224,78,DVB-S,QPSK
+30=11635,H,30000,89,S2,QPSK
+31=11644,V,12000,34,DVB-S,QPSK
+32=11675,V,26040,56,DVB-S,QPSK
+33=11675,H,30000,89,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini
new file mode 100644
index 000000000..c5632384c
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3285.ini
@@ -0,0 +1,13 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3285
+2=Intelsat 25 (31.5W)
+
+[DVB]
+0=4
+1=4114,V,5300,Auto,DVB-S,QPSK
+2=12284,V,2200,23,S2,QPSK
+3=12341,V,2120,78,DVB-S,QPSK
+4=12344,V,2120,78,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini
new file mode 100644
index 000000000..7b1595a53
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3300.ini
@@ -0,0 +1,117 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3300
+2=Hispasat 1D/1E (30.0W)
+
+[DVB]
+0=108
+1=10730,H,27500,34,S2,8PSK
+2=10730,V,30000,34,S2,8PSK
+3=10890,V,27500,34,DVB-S,QPSK
+4=10946,H,4000,910,S2,QPSK
+5=11472,H,5632,34,DVB-S,QPSK
+6=11495,H,6900,34,S2,8PSK
+7=11503,H,4444,34,DVB-S,QPSK
+8=11510,V,10000,34,DVB-S,QPSK
+9=11510,H,4444,34,DVB-S,QPSK
+10=11519,V,2222,56,DVB-S,QPSK
+11=11522,V,2400,34,DVB-S,QPSK
+12=11522,H,4400,34,S2,8PSK
+13=11528,H,4400,34,S2,8PSK
+14=11529,V,10000,910,S2,QPSK
+15=11537,H,4500,34,DVB-S,QPSK
+16=11538,V,4800,34,S2,8PSK
+17=11544,V,4444,34,DVB-S,QPSK
+18=11546,H,4444,34,DVB-S,QPSK
+19=11550,V,5000,34,S2,8PSK
+20=11551,H,5632,34,DVB-S,QPSK
+21=11562,V,5000,34,S2,8PSK
+22=11564,H,4444,34,DVB-S,QPSK
+23=11568,V,5000,34,S2,8PSK
+24=11570,H,4875,34,S2,8PSK
+25=11573,V,7200,34,S2,8PSK
+26=11579,V,2300,34,S2,8PSK
+27=11581,H,3400,23,S2,8PSK
+28=11586,H,3400,23,DVB-S,QPSK
+29=11588,V,3400,23,S2,8PSK
+30=11590,H,3400,23,S2,8PSK
+31=11593,V,3400,23,S2,8PSK
+32=11594,H,3400,23,S2,8PSK
+33=11602,H,6650,34,DVB-S,QPSK
+34=11603,V,6111,34,DVB-S,QPSK
+35=11612,H,4500,34,DVB-S,QPSK
+36=11613,V,4800,34,S2,8PSK
+37=11619,V,4800,34,S2,8PSK
+38=11626,V,4444,34,DVB-S,QPSK
+39=11632,V,4800,34,S2,8PSK
+40=11654,V,5632,34,DVB-S,QPSK
+41=11661,V,4500,34,DVB-S,QPSK
+42=11667,V,4500,34,DVB-S,QPSK
+43=11672,V,2300,56,DVB-S,QPSK
+44=11678,V,2000,56,DVB-S,QPSK
+45=11683,V,3400,34,DVB-S,QPSK
+46=11731,V,27500,34,DVB-S,QPSK
+47=11771,V,27500,34,DVB-S,QPSK
+48=11811,V,27500,34,DVB-S,QPSK
+49=11851,V,27500,34,DVB-S,QPSK
+50=11884,V,27500,23,DVB-S,QPSK
+51=11891,V,30000,56,DVB-S,QPSK
+52=11911,V,12000,34,S2,8PSK
+53=11931,V,27500,34,DVB-S,QPSK
+54=11958,V,2500,78,DVB-S,QPSK
+55=11960,H,6666,34,S2,8PSK
+56=11960,V,1110,Auto,DVB-S,QPSK
+57=11969,H,7200,34,S2,8PSK
+58=11977,V,3255,Auto,DVB-S,QPSK
+59=11983,H,13333,34,DVB-S,QPSK
+60=11987,V,3702,34,DVB-S,QPSK
+61=12052,V,27500,34,DVB-S,QPSK
+62=12052,H,27500,34,DVB-S,QPSK
+63=12076,V,4000,89,S2,QPSK
+64=12092,V,27500,34,DVB-S,QPSK
+65=12092,H,27500,34,DVB-S,QPSK
+66=12108,V,4190,23,DVB-S,QPSK
+67=12130,H,27500,34,S2,8PSK
+68=12132,H,27500,34,DVB-S,QPSK
+69=12169,H,27500,34,S2,8PSK
+70=12207,H,27500,34,S2,8PSK
+71=12226,V,27500,34,DVB-S,QPSK
+72=12246,H,27500,34,S2,8PSK
+73=12303,V,27500,34,DVB-S,QPSK
+74=12322,H,27500,34,DVB-S,QPSK
+75=12360,H,27500,56,DVB-S,QPSK
+76=12380,V,27500,34,DVB-S,QPSK
+77=12399,H,27500,34,S2,8PSK
+78=12425,V,4440,Auto,DVB-S,QPSK
+79=12437,H,27500,34,S2,8PSK
+80=12456,V,30000,56,DVB-S,QPSK
+81=12476,H,27500,34,S2,8PSK
+82=12528,H,4444,34,DVB-S,QPSK
+83=12550,H,3400,34,DVB-S,QPSK
+84=12564,V,4500,34,DVB-S,QPSK
+85=12580,H,9600,34,S2,8PSK
+86=12588,H,4444,34,DVB-S,QPSK
+87=12593,H,3600,34,S2,8PSK
+88=12600,H,3200,34,S2,8PSK
+89=12604,H,3200,34,S2,8PSK
+90=12608,H,3200,34,S2,8PSK
+91=12618,H,6120,34,DVB-S,QPSK
+92=12629,H,4444,34,DVB-S,QPSK
+93=12634,H,4500,34,DVB-S,QPSK
+94=12640,H,4500,34,DVB-S,QPSK
+95=12645,H,4500,34,DVB-S,QPSK
+96=12657,H,7200,34,S2,QPSK
+97=12663,H,5000,34,S2,8PSK
+98=12669,H,3600,34,S2,8PSK
+99=12673,H,3400,34,DVB-S,QPSK
+100=12678,H,3400,23,DVB-S,QPSK
+101=12682,H,3600,34,S2,8PSK
+102=12687,H,4444,34,DVB-S,8PSK
+103=12700,V,1483,34,DVB-S,QPSK
+104=12706,V,4444,34,DVB-S,QPSK
+105=12706,H,20000,12,S2,QPSK
+106=12712,V,7200,34,S2,8PSK
+107=12724,V,4444,34,DVB-S,QPSK
+108=12732,V,4500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini
new file mode 100644
index 000000000..380ed4072
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3325.ini
@@ -0,0 +1,34 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3325
+2=Intelsat 907 (27.5W)
+
+[DVB]
+0=25
+1=3648,V,30000,Auto,S2,QPSK
+2=3718,V,12000,12,DVB-S,QPSK
+3=3723,V,21092,Auto,S2,QPSK
+4=3759,V,26665,Auto,S2,QPSK
+5=3764,V,24450,34,DVB-S,QPSK
+6=3784,H,6510,23,DVB-S,QPSK
+7=3791,H,6510,23,DVB-S,QPSK
+8=3795,V,7000,23,S2,8PSK
+9=3800,V,2400,Auto,DVB-S,QPSK
+10=3802,V,2000,23,DVB-S,QPSK
+11=3831,V,5787,34,DVB-S,QPSK
+12=3838,V,7235,34,DVB-S,QPSK
+13=3855,H,4134,34,S2,8PSK
+14=3859,H,5250,23,S2,8PSK
+15=3873,H,3200,Auto,DVB-S,QPSK
+16=3902,V,1807,34,DVB-S,QPSK
+17=3936,V,4550,12,DVB-S,QPSK
+18=3940,H,2400,Auto,S2,QPSK
+19=4003,H,5632,34,DVB-S,QPSK
+20=4054,V,4000,Auto,S2,QPSK
+21=4110,H,1384,34,DVB-S,QPSK
+22=4119,H,2893,34,DVB-S,QPSK
+23=4151,H,1517,34,DVB-S,QPSK
+24=11050,H,17100,78,DVB-S,QPSK
+25=11495,V,44100,910,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini
new file mode 100644
index 000000000..542d9bd46
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3355.ini
@@ -0,0 +1,106 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3355
+2=Intelsat 905 (24.5W)
+
+[DVB]
+0=97
+1=3653,V,3906,34,DVB-S,QPSK
+2=3688,V,21050,34,DVB-S,QPSK
+3=3829,V,6110,Auto,DVB-S,QPSK
+4=4061,V,2848,23,DVB-S,QPSK
+5=4068,H,2915,78,DVB-S,QPSK
+6=4069,V,3800,12,DVB-S,QPSK
+7=4122,V,5303,12,DVB-S,QPSK
+8=4162,V,6111,34,DVB-S,QPSK
+9=4168,V,3100,23,DVB-S,QPSK
+10=4181,V,6111,34,DVB-S,QPSK
+11=4192,H,2100,23,DVB-S,QPSK
+12=10957,V,6660,34,S2,8PSK
+13=10963,V,4800,34,S2,8PSK
+14=10976,V,7200,34,S2,8PSK
+15=10987,V,5000,35,S2,QPSK
+16=10992,V,4800,34,S2,8PSK
+17=10997,H,6666,56,DVB-S,QPSK
+18=10998,V,4800,34,S2,8PSK
+19=11004,H,3300,78,DVB-S,QPSK
+20=11004,V,4800,34,S2,8PSK
+21=11007,H,1600,56,S2,8PSK
+22=11010,V,4800,34,S2,8PSK
+23=11011,H,3100,78,DVB-S,QPSK
+24=11015,H,1600,56,S2,8PSK
+25=11017,H,1600,56,S2,8PSK
+26=11020,V,3550,34,S2,8PSK
+27=11022,H,4280,34,DVB-S,QPSK
+28=11028,H,4280,34,DVB-S,QPSK
+29=11041,V,3750,34,S2,8PSK
+30=11042,H,1600,56,S2,8PSK
+31=11045,V,3750,34,S2,8PSK
+32=11046,H,3400,23,S2,8PSK
+33=11049,V,6620,34,DVB-S,QPSK
+34=11050,H,3200,56,S2,8PSK
+35=11054,H,3700,34,S2,8PSK
+36=11060,H,3400,23,S2,8PSK
+37=11060,V,7200,34,S2,8PSK
+38=11068,H,3111,34,DVB-S,QPSK
+39=11072,V,4444,34,DVB-S,QPSK
+40=11078,H,3400,23,S2,8PSK
+41=11079,V,6111,34,DVB-S,QPSK
+42=11082,H,3400,23,S2,8PSK
+43=11084,V,4444,34,DVB-S,QPSK
+44=11086,H,1600,56,S2,8PSK
+45=11090,V,4444,34,DVB-S,QPSK
+46=11090,H,4444,34,DVB-S,QPSK
+47=11095,H,4800,34,S2,8PSK
+48=11096,V,4444,34,DVB-S,QPSK
+49=11103,V,3400,34,S2,8PSK
+50=11108,V,3400,23,S2,8PSK
+51=11108,H,4445,34,DVB-S,QPSK
+52=11121,H,3400,23,S2,8PSK
+53=11122,V,7200,34,S2,8PSK
+54=11126,H,3400,23,S2,8PSK
+55=11130,H,3400,23,S2,8PSK
+56=11132,V,14115,12,DVB-S,QPSK
+57=11134,H,3400,23,S2,8PSK
+58=11139,H,3400,23,S2,8PSK
+59=11144,H,3400,23,S2,8PSK
+60=11148,H,3400,23,S2,8PSK
+61=11148,V,3200,34,DVB-S,QPSK
+62=11152,H,3400,23,S2,8PSK
+63=11157,V,3400,23,S2,8PSK
+64=11157,H,3400,23,S2,8PSK
+65=11161,V,3400,23,S2,8PSK
+66=11162,H,3400,23,S2,8PSK
+67=11165,V,4834,56,S2,QPSK
+68=11166,H,3400,23,S2,8PSK
+69=11171,H,3516,34,S2,8PSK
+70=11177,V,6666,78,DVB-S,QPSK
+71=11177,H,7200,34,S2,8PSK
+72=11182,H,3400,23,S2,8PSK
+73=11187,H,1600,56,S2,8PSK
+74=11188,V,3400,23,S2,8PSK
+75=11193,V,4666,34,S2,QPSK
+76=11455,V,3450,34,DVB-S,QPSK
+77=11463,V,3583,89,S2,QPSK
+78=11471,V,3400,23,S2,8PSK
+79=11476,V,3400,23,S2,8PSK
+80=11477,H,27500,34,DVB-S,QPSK
+81=11488,V,11640,56,S2,8PSK
+82=11509,V,3750,34,DVB-S,QPSK
+83=11513,H,27500,34,DVB-S,QPSK
+84=11518,V,7100,12,S2,8PSK
+85=11527,V,2600,45,S2,QPSK
+86=11530,V,2000,34,DVB-S,QPSK
+87=11580,H,7120,34,S2,8PSK
+88=11589,H,7120,34,S2,8PSK
+89=11598,H,7120,34,S2,8PSK
+90=11608,H,7120,34,S2,8PSK
+91=11620,V,3600,34,S2,8PSK
+92=11626,H,13500,78,DVB-S,QPSK
+93=11636,H,3500,23,S2,8PSK
+94=11638,V,21000,56,S2,8PSK
+95=11642,H,3400,23,S2,8PSK
+96=11646,H,1600,56,S2,8PSK
+97=11650,H,3200,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini
new file mode 100644
index 000000000..39d26fdbb
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3380.ini
@@ -0,0 +1,64 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3380
+2=SES 4 (22.0W)
+
+[DVB]
+0=55
+1=3631,V,7200,34,S2,8PSK
+2=3631,H,7200,Auto,S2,QPSK
+3=3713,V,3254,23,DVB-S,QPSK
+4=3724,H,30000,23,S2,8PSK
+5=3726,H,1000,34,S2,8PSK
+6=3761,V,22650,23,DVB-S,QPSK
+7=3825,H,8950,56,DVB-S,QPSK
+8=3966,H,2221,23,DVB-S,QPSK
+9=3970,H,3332,34,DVB-S,QPSK
+10=3976,H,1844,34,DVB-S,QPSK
+11=4016,H,3662,23,DVB-S,QPSK
+12=4033,V,3689,34,DVB-S,QPSK
+13=4039,V,3906,34,DVB-S,QPSK
+14=4043,V,3560,23,S2,8PSK
+15=4048,V,3333,23,DVB-S,QPSK
+16=4053,V,3333,23,DVB-S,QPSK
+17=4056,V,2441,23,DVB-S,QPSK
+18=4061,V,3333,Auto,S2,8PSK
+19=4065,H,3590,34,S2,QPSK
+20=4071,V,3502,34,DVB-S,QPSK
+21=4097,V,23500,34,S2,QPSK
+22=4115,H,3680,23,DVB-S,QPSK
+23=4141,H,1925,45,S2,QPSK
+24=10986,V,30000,34,DVB-S,QPSK
+25=11108,H,15000,56,S2,8PSK
+26=11128,H,14300,35,S2,8PSK
+27=11540,H,12238,45,S2,QPSK
+28=11551,V,40000,Auto,S2,8PSK
+29=11552,H,3255,12,DVB-S,QPSK
+30=11563,H,6111,34,DVB-S,QPSK
+31=11574,H,7500,56,S2,8PSK
+32=11667,H,7500,910,S2,8PSK
+33=11671,V,30000,34,DVB-S,QPSK
+34=11674,H,3500,34,DVB-S,QPSK
+35=11684,H,8570,910,S2,8PSK
+36=11693,H,7500,910,S2,8PSK
+37=11777,H,4000,34,DVB-S,QPSK
+38=11861,H,35000,34,DVB-S,QPSK
+39=11921,H,35000,34,DVB-S,QPSK
+40=12037,H,4610,34,S2,8PSK
+41=12076,H,4610,34,S2,8PSK
+42=12082,H,4610,34,S2,8PSK
+43=12089,H,4610,34,S2,8PSK
+44=12530,V,30000,34,DVB-S,QPSK
+45=12570,V,30000,34,DVB-S,QPSK
+46=12610,V,30000,34,DVB-S,QPSK
+47=12635,H,4610,34,S2,8PSK
+48=12644,H,5136,34,DVB-S,QPSK
+49=12650,V,30000,34,DVB-S,QPSK
+50=12653,H,3055,34,DVB-S,QPSK
+51=12658,H,3055,34,DVB-S,QPSK
+52=12673,H,20250,34,DVB-S,QPSK
+53=12690,V,30000,34,DVB-S,QPSK
+54=12717,H,1500,34,S2,8PSK
+55=12730,V,30000,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini
new file mode 100644
index 000000000..c23fe0b19
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3400.ini
@@ -0,0 +1,18 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3400
+2=NSS 7 (20.0W)
+
+[DVB]
+0=9
+1=3969,V,3410,Auto,DVB-S,QPSK
+2=3973,V,3410,Auto,DVB-S,QPSK
+3=3977,V,3410,Auto,DVB-S,QPSK
+4=4129,V,15405,12,S2,QPSK
+5=11166,H,7500,34,S2,8PSK
+6=11175,H,7500,34,S2,8PSK
+7=11184,H,7500,34,S2,8PSK
+8=11192,H,7500,34,S2,8PSK
+9=11585,H,2200,12,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini
new file mode 100644
index 000000000..2470d71f9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3420.ini
@@ -0,0 +1,16 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3420
+2=Intelsat 901 (18.0W)
+
+[DVB]
+0=7
+1=3631,V,1600,56,S2,8PSK
+2=3887,H,26500,Auto,DVB-S,QPSK
+3=3961,H,2960,78,DVB-S,QPSK
+4=4010,V,6730,34,S2,QPSK
+5=4018,V,4444,23,DVB-S,QPSK
+6=4027,V,9037,56,S2,8PSK
+7=11033,V,2530,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini
new file mode 100644
index 000000000..cae2fe8b9
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3450.ini
@@ -0,0 +1,92 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3450
+2=Telstar 12 (15.0W)
+
+[DVB]
+0=83
+1=10997,V,2894,34,DVB-S,QPSK
+2=11005,H,8880,34,DVB-S,QPSK
+3=11012,V,3400,34,DVB-S,QPSK
+4=11016,V,3333,34,DVB-S,QPSK
+5=11033,V,2130,34,DVB-S,QPSK
+6=11063,V,7200,34,S2,8PSK
+7=11079,H,4610,34,S2,8PSK
+8=11088,H,7500,34,S2,8PSK
+9=11123,H,21600,34,DVB-S,QPSK
+10=11123,V,21540,34,S2,8PSK
+11=11150,H,21600,34,DVB-S,QPSK
+12=11150,V,19279,34,DVB-S,QPSK
+13=11457,V,3255,34,DVB-S,QPSK
+14=11472,H,3310,34,DVB-S,QPSK
+15=11477,H,4500,34,DVB-S,QPSK
+16=11487,H,7200,34,S2,QPSK
+17=11497,H,7200,34,S2,8PSK
+18=11498,V,6111,34,DVB-S,QPSK
+19=11524,H,14400,34,S2,8PSK
+20=11534,H,3200,78,DVB-S,QPSK
+21=11539,H,4610,34,DVB-S,QPSK
+22=11545,V,4088,34,DVB-S,QPSK
+23=11546,H,4610,34,S2,8PSK
+24=11564,H,7500,34,S2,8PSK
+25=11591,V,2893,34,DVB-S,QPSK
+26=11597,V,3200,78,DVB-S,QPSK
+27=11604,V,1810,78,DVB-S,QPSK
+28=11604,H,5886,23,DVB-S,QPSK
+29=11611,H,4054,34,S2,8PSK
+30=11618,H,7000,56,S2,8PSK
+31=11625,V,3979,34,DVB-S,QPSK
+32=11627,H,7000,34,S2,8PSK
+33=11642,H,4610,34,S2,8PSK
+34=11644,V,5632,34,DVB-S,QPSK
+35=11651,V,5632,34,DVB-S,QPSK
+36=11651,H,4610,34,S2,8PSK
+37=11662,V,6111,78,DVB-S,QPSK
+38=11667,H,3255,78,DVB-S,QPSK
+39=11671,V,6666,78,DVB-S,QPSK
+40=11690,V,2200,34,DVB-S,QPSK
+41=11691,H,6111,34,DVB-S,QPSK
+42=11709,V,3198,78,DVB-S,QPSK
+43=11710,H,6750,Auto,DVB-S,QPSK
+44=11720,H,6600,Auto,DVB-S,QPSK
+45=11726,V,3200,Auto,DVB-S,QPSK
+46=11737,H,6600,Auto,DVB-S,QPSK
+47=11755,V,5500,Auto,DVB-S,QPSK
+48=11771,V,4800,23,S2,8PSK
+49=11860,H,45000,Auto,S2,8PSK
+50=11920,H,45000,Auto,S2,8PSK
+51=11964,H,14714,23,DVB-S,QPSK
+52=11993,H,6666,78,DVB-S,QPSK
+53=12004,H,6111,Auto,DVB-S,QPSK
+54=12044,H,45000,Auto,S2,8PSK
+55=12087,V,3200,34,DVB-S,QPSK
+56=12094,V,2000,34,DVB-S,QPSK
+57=12100,V,3200,78,DVB-S,QPSK
+58=12107,V,3330,Auto,DVB-S,QPSK
+59=12123,V,3480,78,DVB-S,QPSK
+60=12126,V,2000,56,DVB-S,QPSK
+61=12170,H,45000,56,S2,QPSK
+62=12509,H,3198,78,DVB-S,QPSK
+63=12511,V,7552,34,DVB-S,QPSK
+64=12513,H,3400,34,S2,8PSK
+65=12518,H,3198,78,DVB-S,QPSK
+66=12521,H,3198,78,DVB-S,QPSK
+67=12570,V,2900,34,S2,8PSK
+68=12570,H,2900,34,S2,8PSK
+69=12573,V,2900,34,S2,8PSK
+70=12584,H,3976,34,DVB-S,QPSK
+71=12589,H,1925,78,DVB-S,QPSK
+72=12608,H,19279,23,DVB-S,QPSK
+73=12620,V,3012,23,DVB-S,QPSK
+74=12645,H,3255,34,DVB-S,QPSK
+75=12658,H,3255,78,DVB-S,QPSK
+76=12662,V,8000,34,DVB-S,QPSK
+77=12666,H,3255,78,DVB-S,QPSK
+78=12674,H,5632,34,DVB-S,QPSK
+79=12676,V,14170,34,S2,8PSK
+80=12696,H,5632,34,DVB-S,QPSK
+81=12705,H,5632,34,DVB-S,QPSK
+82=12710,V,6666,78,DVB-S,QPSK
+83=12740,V,5632,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini
new file mode 100644
index 000000000..46a7c1b62
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3460.ini
@@ -0,0 +1,11 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3460
+2=Express A4 (14.0W)
+
+[DVB]
+0=2
+1=3975,V,30000,34,S2,QPSK
+2=4025,V,30000,34,S2,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini
new file mode 100644
index 000000000..e7a7afc1d
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3475.ini
@@ -0,0 +1,116 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3475
+2=Eutelsat 12 West A (12.5W)
+
+[DVB]
+0=107
+1=10958,H,4940,34,S2,8PSK
+2=10965,H,4444,78,DVB-S,QPSK
+3=10971,H,4444,78,DVB-S,QPSK
+4=10977,H,4444,78,DVB-S,QPSK
+5=10983,H,4444,78,DVB-S,QPSK
+6=10989,H,4444,78,DVB-S,QPSK
+7=10995,H,4940,34,S2,8PSK
+8=11001,H,4444,78,DVB-S,QPSK
+9=11007,H,4444,78,DVB-S,QPSK
+10=11013,H,4900,34,S2,8PSK
+11=11019,H,4444,78,DVB-S,QPSK
+12=11022,V,6666,78,DVB-S,QPSK
+13=11025,H,4444,78,DVB-S,QPSK
+14=11040,H,3270,56,DVB-S,QPSK
+15=11044,H,3270,56,DVB-S,QPSK
+16=11048,H,3270,56,DVB-S,8PSK
+17=11052,H,3270,56,DVB-S,QPSK
+18=11058,H,3270,56,DVB-S,QPSK
+19=11062,H,3270,56,DVB-S,QPSK
+20=11064,V,7500,910,S2,8PSK
+21=11068,H,3333,34,DVB-S,QPSK
+22=11070,V,3680,56,DVB-S,QPSK
+23=11072,H,4500,34,DVB-S,QPSK
+24=11075,V,3630,56,S2,8PSK
+25=11079,V,3270,56,DVB-S,QPSK
+26=11081,H,6511,34,DVB-S,QPSK
+27=11083,V,3270,56,DVB-S,QPSK
+28=11087,H,3400,34,S2,8PSK
+29=11088,V,3400,56,DVB-S,QPSK
+30=11091,H,3333,34,DVB-S,QPSK
+31=11093,V,3270,56,DVB-S,QPSK
+32=11097,V,3630,23,S2,8PSK
+33=11103,V,3630,23,S2,8PSK
+34=11108,V,3250,56,DVB-S,QPSK
+35=11125,V,7100,34,DVB-S,QPSK
+36=11126,H,4800,34,S2,8PSK
+37=11135,V,7100,34,DVB-S,QPSK
+38=11142,H,4208,56,S2,8PSK
+39=11149,H,4208,56,S2,8PSK
+40=11153,H,3204,34,DVB-S,QPSK
+41=11160,H,3270,56,DVB-S,QPSK
+42=11164,H,3270,56,DVB-S,QPSK
+43=11171,H,7200,34,S2,8PSK
+44=11181,H,7390,34,S2,8PSK
+45=11188,H,3600,35,S2,8PSK
+46=11192,H,3600,35,S2,8PSK
+47=11329,H,3214,56,DVB-S,8PSK
+48=11334,H,3214,56,DVB-S,QPSK
+49=11340,H,2136,34,DVB-S,QPSK
+50=11350,H,6700,34,S2,8PSK
+51=11359,H,6700,34,S2,8PSK
+52=11371,H,3400,34,DVB-S,QPSK
+53=11375,H,3400,34,DVB-S,QPSK
+54=11380,H,3215,34,DVB-S,QPSK
+55=11393,H,12750,78,DVB-S,QPSK
+56=11403,H,6111,34,DVB-S,QPSK
+57=11408,V,27500,34,DVB-S,QPSK
+58=11414,H,7120,34,S2,8PSK
+59=11424,H,7120,34,S2,8PSK
+60=11431,H,6700,34,S2,8PSK
+61=11442,H,7120,34,S2,8PSK
+62=11597,H,3884,Auto,DVB-S,QPSK
+63=11622,H,3255,Auto,DVB-S,QPSK
+64=11643,H,2398,Auto,DVB-S,QPSK
+65=11645,V,4790,Auto,DVB-S,QPSK
+66=11647,H,3992,Auto,DVB-S,QPSK
+67=11651,V,3688,Auto,DVB-S,QPSK
+68=11655,H,6666,56,DVB-S,QPSK
+69=11664,H,6111,34,DVB-S,QPSK
+70=11690,H,5700,34,DVB-S,QPSK
+71=12507,V,3125,34,DVB-S,QPSK
+72=12514,H,3600,34,S2,8PSK
+73=12520,H,3400,34,DVB-S,QPSK
+74=12521,V,2400,34,DVB-S,QPSK
+75=12532,V,7360,56,S2,8PSK
+76=12540,V,3111,78,DVB-S,QPSK
+77=12546,V,6111,34,DVB-S,QPSK
+78=12555,V,4104,23,S2,QPSK
+79=12574,V,3400,34,DVB-S,QPSK
+80=12577,H,2222,56,S2,QPSK
+81=12583,H,2894,34,DVB-S,QPSK
+82=12590,H,3600,23,DVB-S,QPSK
+83=12595,H,1875,56,S2,8PSK
+84=12606,H,2500,56,S2,8PSK
+85=12606,V,3600,34,S2,8PSK
+86=12614,H,8570,34,S2,8PSK
+87=12614,V,8570,34,S2,8PSK
+88=12634,V,7200,34,S2,8PSK
+89=12638,H,14400,34,S2,8PSK
+90=12648,V,9874,34,S2,8PSK
+91=12650,H,3600,34,S2,8PSK
+92=12661,V,4444,34,DVB-S,QPSK
+93=12668,H,3213,34,DVB-S,QPSK
+94=12668,V,3270,56,DVB-S,QPSK
+95=12672,H,2141,34,DVB-S,QPSK
+96=12672,V,3270,56,DVB-S,QPSK
+97=12676,H,3178,34,DVB-S,QPSK
+98=12679,V,7500,34,S2,8PSK
+99=12681,H,3178,34,DVB-S,QPSK
+100=12694,V,1580,56,S2,8PSK
+101=12696,V,1580,56,S2,8PSK
+102=12699,V,1580,56,S2,8PSK
+103=12717,V,3333,78,DVB-S,QPSK
+104=12718,H,36510,56,S2,8PSK
+105=12723,V,6111,34,DVB-S,QPSK
+106=12730,V,3254,34,DVB-S,QPSK
+107=12739,V,7500,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini
new file mode 100644
index 000000000..7d5737979
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3490.ini
@@ -0,0 +1,39 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3490
+2=Express AM44 (11.0W)
+
+[DVB]
+0=30
+1=3662,V,10808,12,DVB-S,QPSK
+2=4092,V,2224,35,S2,8PSK
+3=10957,V,2300,56,S2,8PSK
+4=10983,V,12110,Auto,DVB-S,QPSK
+5=11059,H,3124,34,DVB-S,QPSK
+6=11095,H,3000,34,DVB-S,QPSK
+7=11144,H,3214,34,S2,8PSK
+8=11154,H,7200,34,S2,8PSK
+9=11174,H,9874,34,S2,8PSK
+10=11191,H,7200,34,S2,8PSK
+11=11479,H,7500,34,S2,8PSK
+12=11483,V,3470,78,DVB-S,QPSK
+13=11492,H,6428,34,DVB-S,QPSK
+14=11499,H,3214,34,DVB-S,QPSK
+15=11505,H,2222,34,S2,8PSK
+16=11522,H,1185,23,DVB-S,QPSK
+17=11523,H,1280,56,S2,8PSK
+18=11533,H,3333,34,DVB-S,QPSK
+19=11542,H,3600,34,S2,QPSK
+20=11542,V,2170,56,DVB-S,QPSK
+21=11566,H,8000,34,S2,8PSK
+22=11581,H,2050,34,DVB-S,QPSK
+23=11599,H,3600,56,DVB-S,QPSK
+24=11603,H,3333,34,DVB-S,QPSK
+25=11608,H,5000,34,DVB-S,QPSK
+26=11612,H,3333,34,DVB-S,QPSK
+27=11618,H,3333,34,DVB-S,QPSK
+28=11628,H,6422,56,DVB-S,QPSK
+29=11642,H,3333,34,DVB-S,QPSK
+30=11669,H,5000,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini
new file mode 100644
index 000000000..6274b967e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3520.ini
@@ -0,0 +1,80 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3520
+2=Eutelsat 8 West A (8.0W)
+
+[DVB]
+0=71
+1=11471,V,27500,56,DVB-S,QPSK
+2=11512,V,27500,56,DVB-S,QPSK
+3=11554,V,27500,34,DVB-S,QPSK
+4=11595,V,27500,34,DVB-S,QPSK
+5=11637,V,27500,34,DVB-S,QPSK
+6=11678,H,30000,Auto,S2,QPSK
+7=11678,V,27500,34,DVB-S,QPSK
+8=12509,V,4150,34,S2,QPSK
+9=12509,H,5000,34,S2,8PSK
+10=12513,V,4150,34,S2,QPSK
+11=12515,H,2500,Auto,S2,8PSK
+12=12518,V,4150,34,S2,QPSK
+13=12523,V,4150,34,S2,QPSK
+14=12524,H,9600,34,S2,8PSK
+15=12527,V,4150,34,S2,QPSK
+16=12531,V,3488,56,S2,8PSK
+17=12536,V,4150,34,S2,QPSK
+18=12549,H,4800,34,S2,8PSK
+19=12550,V,2267,56,S2,8PSK
+20=12554,H,3600,34,S2,8PSK
+21=12554,V,2267,56,S2,8PSK
+22=12558,V,2267,56,S2,8PSK
+23=12558,H,3600,34,S2,8PSK
+24=12561,V,2267,56,S2,8PSK
+25=12564,V,2267,56,S2,8PSK
+26=12567,V,2267,56,S2,8PSK
+27=12570,V,2267,56,S2,8PSK
+28=12572,H,7200,34,S2,8PSK
+29=12573,V,2267,56,S2,8PSK
+30=12578,V,2267,56,S2,8PSK
+31=12580,H,3200,56,S2,8PSK
+32=12582,V,2744,56,S2,8PSK
+33=12585,H,3124,34,DVB-S,QPSK
+34=12589,H,9874,34,S2,8PSK
+35=12592,V,4800,34,S2,QPSK
+36=12599,V,3333,78,DVB-S,QPSK
+37=12601,H,6975,56,S2,8PSK
+38=12606,V,1300,910,S2,8PSK
+39=12609,V,2400,56,S2,8PSK
+40=12613,H,3056,34,S2,QPSK
+41=12614,V,2400,56,S2,8PSK
+42=12619,V,2400,56,S2,8PSK
+43=12624,H,7200,34,S2,8PSK
+44=12627,V,2222,12,DVB-S,QPSK
+45=12632,V,2500,56,S2,8PSK
+46=12633,H,7200,34,S2,8PSK
+47=12638,H,3055,34,DVB-S,QPSK
+48=12640,V,5000,34,S2,8PSK
+49=12646,V,5000,34,S2,8PSK
+50=12652,V,5000,34,S2,8PSK
+51=12656,H,7200,34,S2,8PSK
+52=12658,V,5000,56,S2,8PSK
+53=12666,H,5632,34,DVB-S,QPSK
+54=12673,H,2778,34,DVB-S,QPSK
+55=12676,H,2778,34,DVB-S,QPSK
+56=12676,V,5632,34,DVB-S,QPSK
+57=12684,H,5632,34,DVB-S,QPSK
+58=12686,V,6111,34,DVB-S,QPSK
+59=12695,V,6111,34,DVB-S,QPSK
+60=12703,V,5632,34,DVB-S,QPSK
+61=12705,H,4800,34,S2,8PSK
+62=12715,H,9600,34,S2,8PSK
+63=12718,V,7200,34,S2,8PSK
+64=12725,V,2267,56,S2,8PSK
+65=12727,H,9600,34,S2,8PSK
+66=12735,V,3600,34,S2,8PSK
+67=12739,H,9600,34,S2,8PSK
+68=12741,V,3600,34,S2,8PSK
+69=12744,V,3270,56,S2,8PSK
+70=12747,H,4800,34,S2,8PSK
+71=12747,V,3600,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini
new file mode 100644
index 000000000..b5aa21780
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3527.ini
@@ -0,0 +1,94 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3527
+2=Eutelsat 7 West A/Eutelsat 8 West C/Nilesat 102/201 (7.3W)
+
+[DVB]
+0=85
+1=10719,V,22000,34,S2,QPSK
+2=10727,H,27500,56,DVB-S,QPSK
+3=10758,V,27500,56,DVB-S,QPSK
+4=10777,H,27500,56,DVB-S,QPSK
+5=10796,V,27500,56,DVB-S,QPSK
+6=10815,H,27500,56,DVB-S,QPSK
+7=10834,V,27500,23,S2,8PSK
+8=10853,H,27500,23,S2,8PSK
+9=10873,V,27500,56,DVB-S,QPSK
+10=10892,H,27500,34,DVB-S,QPSK
+11=10922,V,27500,56,DVB-S,QPSK
+12=10930,H,27500,56,DVB-S,QPSK
+13=10971,H,27500,34,DVB-S,QPSK
+14=10992,V,27500,34,DVB-S,QPSK
+15=11006,H,17000,23,S2,8PSK
+16=11034,V,27500,34,DVB-S,QPSK
+17=11054,H,27500,34,DVB-S,QPSK
+18=11075,V,27500,34,DVB-S,QPSK
+19=11096,H,27500,34,DVB-S,QPSK
+20=11117,V,27500,34,DVB-S,QPSK
+21=11137,H,27500,34,DVB-S,QPSK
+22=11158,V,27500,56,DVB-S,QPSK
+23=11179,H,27500,34,DVB-S,QPSK
+24=11219,H,27500,56,DVB-S,QPSK
+25=11227,V,27500,56,DVB-S,QPSK
+26=11258,H,27500,56,DVB-S,QPSK
+27=11277,V,27500,23,S2,8PSK
+28=11296,H,27500,34,DVB-S,QPSK
+29=11315,V,27500,56,DVB-S,QPSK
+30=11334,H,27500,56,DVB-S,QPSK
+31=11354,V,27500,56,DVB-S,QPSK
+32=11373,H,27500,23,S2,8PSK
+33=11392,V,27500,56,DVB-S,QPSK
+34=11411,H,27500,23,S2,8PSK
+35=11430,V,27500,56,DVB-S,QPSK
+36=11449,H,27500,56,DVB-S,QPSK
+37=11476,V,27500,34,DVB-S,8PSK
+38=11488,H,27500,56,DVB-S,QPSK
+39=11526,H,27500,56,DVB-S,QPSK
+40=11559,V,27500,56,S2,8PSK
+41=11564,H,27500,56,DVB-S,QPSK
+42=11595,V,27500,34,DVB-S,QPSK
+43=11603,H,27500,56,DVB-S,QPSK
+44=11641,H,27500,56,DVB-S,QPSK
+45=11661,V,27500,23,DVB-S,QPSK
+46=11680,H,27500,56,DVB-S,QPSK
+47=11727,H,27500,56,S2,8PSK
+48=11747,V,27500,34,DVB-S,QPSK
+49=11766,H,27500,56,DVB-S,QPSK
+50=11785,V,27500,34,DVB-S,QPSK
+51=11804,H,27500,56,S2,QPSK
+52=11823,V,27500,56,DVB-S,QPSK
+53=11843,H,27500,56,DVB-S,QPSK
+54=11862,V,27500,34,S2,8PSK
+55=11881,H,27500,56,S2,QPSK
+56=11900,V,27500,56,DVB-S,QPSK
+57=11919,H,27500,34,S2,8PSK
+58=11938,V,27500,34,DVB-S,QPSK
+59=11958,H,27500,56,DVB-S,QPSK
+60=11977,V,27500,56,DVB-S,QPSK
+61=11996,H,27500,23,S2,8PSK
+62=12015,V,27500,56,DVB-S,QPSK
+63=12034,H,27500,56,DVB-S,QPSK
+64=12054,V,27500,56,DVB-S,QPSK
+65=12073,H,27500,23,S2,8PSK
+66=12092,V,27500,56,S2,QPSK
+67=12111,H,27500,34,DVB-S,QPSK
+68=12130,V,27500,56,DVB-S,QPSK
+69=12169,V,27500,56,DVB-S,QPSK
+70=12188,H,27500,56,S2,QPSK
+71=12207,V,27500,34,DVB-S,QPSK
+72=12226,H,27500,34,DVB-S,QPSK
+73=12245,V,27500,23,S2,8PSK
+74=12265,H,27500,23,S2,8PSK
+75=12284,V,27500,34,DVB-S,QPSK
+76=12303,H,27500,56,DVB-S,QPSK
+77=12322,V,27500,23,S2,8PSK
+78=12341,H,27500,56,DVB-S,QPSK
+79=12360,V,27500,34,DVB-S,QPSK
+80=12380,H,27500,56,DVB-S,QPSK
+81=12399,V,27500,56,DVB-S,QPSK
+82=12418,H,27500,34,DVB-S,QPSK
+83=12437,V,27500,56,DVB-S,QPSK
+84=12467,H,27500,23,S2,8PSK
+85=12476,V,27500,23,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini
new file mode 100644
index 000000000..5ae30b778
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3550.ini
@@ -0,0 +1,69 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3550
+2=Eutelsat 5 West A (5.0W)
+
+[DVB]
+0=60
+1=3630,V,3255,23,DVB-S,QPSK
+2=3633,V,2018,78,DVB-S,QPSK
+3=3646,V,2170,34,DVB-S,QPSK
+4=3656,V,2917,35,S2,8PSK
+5=3712,H,2480,78,DVB-S,QPSK
+6=3717,H,2222,56,S2,8PSK
+7=3719,H,1286,23,S2,8PSK
+8=3721,H,1837,34,S2,8PSK
+9=3727,V,29950,78,DVB-S,QPSK
+10=3743,H,2785,56,DVB-S,QPSK
+11=4015,V,3591,34,S2,8PSK
+12=4021,V,1245,34,S2,8PSK
+13=4022,V,1200,34,S2,8PSK
+14=4030,V,4593,35,S2,8PSK
+15=4077,H,3100,56,S2,QPSK
+16=4110,H,2141,56,S2,QPSK
+17=4114,H,2143,56,DVB-S,QPSK
+18=4123,V,8319,34,DVB-S,QPSK
+19=4137,H,2510,78,DVB-S,QPSK
+20=4138,V,4434,78,DVB-S,QPSK
+21=4154,H,2289,78,DVB-S,QPSK
+22=4154,V,28485,56,S2,8PSK
+23=4156,H,1793,78,DVB-S,QPSK
+24=4159,H,1944,78,DVB-S,QPSK
+25=4162,H,1500,34,DVB-S,QPSK
+26=10972,V,29950,78,DVB-S,QPSK
+27=11054,V,29950,78,DVB-S,QPSK
+28=11059,H,23700,34,DVB-S,QPSK
+29=11096,V,29950,34,S2,8PSK
+30=11108,H,3125,34,DVB-S,QPSK
+31=11168,H,6111,34,DVB-S,QPSK
+32=11177,H,6111,34,DVB-S,QPSK
+33=11184,H,5632,34,DVB-S,QPSK
+34=11195,H,3333,34,DVB-S,QPSK
+35=11456,H,2400,34,S2,QPSK
+36=11460,H,1704,34,S2,8PSK
+37=11469,H,3100,78,DVB-S,QPSK
+38=11471,V,29950,34,S2,8PSK
+39=11472,H,2000,34,S2,8PSK
+40=11480,H,3215,34,S2,8PSK
+41=11496,H,6111,34,DVB-S,QPSK
+42=11505,H,5632,34,DVB-S,QPSK
+43=11512,V,29950,78,DVB-S,QPSK
+44=11513,H,5632,34,DVB-S,QPSK
+45=11522,H,6111,34,DVB-S,QPSK
+46=11538,H,8681,78,DVB-S,QPSK
+47=11554,V,29950,78,DVB-S,QPSK
+48=11591,V,20000,23,DVB-S,QPSK
+49=11592,H,25000,12,S2,QPSK
+50=11604,H,3333,34,DVB-S,QPSK
+51=11608,H,3333,34,DVB-S,QPSK
+52=11609,V,5968,12,DVB-S,QPSK
+53=11634,H,29950,34,S2,8PSK
+54=11679,V,29950,78,DVB-S,QPSK
+55=12522,V,29950,23,S2,8PSK
+56=12543,H,27500,34,DVB-S,QPSK
+57=12564,V,29950,78,DVB-S,QPSK
+58=12648,V,29500,89,S2,8PSK
+59=12654,H,5500,23,S2,8PSK
+60=12690,V,30000,35,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini
new file mode 100644
index 000000000..bf3006b2e
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3560.ini
@@ -0,0 +1,73 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3560
+2=Amos 2/3 (4.0W)
+
+[DVB]
+0=64
+1=10722,V,30000,23,S2,8PSK
+2=10722,H,27500,34,DVB-S,QPSK
+3=10758,V,30000,34,S2,8PSK
+4=10759,H,30000,34,DVB-S,QPSK
+5=10806,V,30000,34,S2,8PSK
+6=10806,H,30000,34,DVB-S,QPSK
+7=10842,V,30000,34,S2,8PSK
+8=10876,H,7500,23,S2,8PSK
+9=10888,H,11570,34,DVB-S,QPSK
+10=10889,V,30000,34,S2,8PSK
+11=10890,V,27500,56,DVB-S,QPSK
+12=10921,H,7500,23,S2,8PSK
+13=10925,V,27500,56,DVB-S,QPSK
+14=10926,V,30000,34,S2,8PSK
+15=10935,H,13750,56,DVB-S,QPSK
+16=10959,H,3700,34,DVB-S,QPSK
+17=10972,V,30000,23,S2,8PSK
+18=11006,H,3700,34,DVB-S,QPSK
+19=11008,V,30000,23,S2,8PSK
+20=11015,H,2295,34,DVB-S,QPSK
+21=11130,H,10000,23,S2,8PSK
+22=11140,H,3200,Auto,DVB-S,QPSK
+23=11166,H,3333,34,DVB-S,QPSK
+24=11180,H,5650,34,DVB-S,QPSK
+25=11190,H,3400,34,DVB-S,QPSK
+26=11222,V,27500,56,DVB-S,QPSK
+27=11222,H,30000,56,S2,QPSK
+28=11258,V,27500,56,DVB-S,QPSK
+29=11291,H,2800,34,DVB-S,QPSK
+30=11304,H,13330,34,DVB-S,QPSK
+31=11315,H,5000,34,S2,8PSK
+32=11332,H,12500,78,DVB-S,QPSK
+33=11389,H,27500,34,DVB-S,QPSK
+34=11411,H,3330,34,DVB-S,QPSK
+35=11432,H,2500,34,DVB-S,QPSK
+36=11435,H,2600,34,DVB-S,QPSK
+37=11474,V,27500,34,DVB-S,QPSK
+38=11510,V,30000,23,S2,8PSK
+39=11541,V,2963,34,DVB-S,QPSK
+40=11542,H,3700,34,DVB-S,QPSK
+41=11544,V,1480,56,DVB-S,QPSK
+42=11546,V,2600,56,S2,8PSK
+43=11547,H,3333,34,DVB-S,QPSK
+44=11549,V,1240,34,DVB-S,QPSK
+45=11551,H,3333,56,DVB-S,QPSK
+46=11552,V,1222,78,DVB-S,QPSK
+47=11555,V,1240,78,DVB-S,QPSK
+48=11565,V,3000,34,DVB-S,QPSK
+49=11578,V,1222,78,DVB-S,QPSK
+50=11580,V,1110,78,DVB-S,QPSK
+51=11601,H,8888,34,DVB-S,QPSK
+52=11610,H,3600,34,DVB-S,QPSK
+53=11624,H,2604,56,DVB-S,QPSK
+54=11625,V,3000,34,DVB-S,QPSK
+55=11627,V,6295,34,S2,QPSK
+56=11635,H,6333,34,DVB-S,QPSK
+57=11635,V,4410,56,DVB-S,QPSK
+58=11639,V,2000,56,DVB-S,QPSK
+59=11647,V,8518,34,DVB-S,QPSK
+60=11658,H,3333,34,DVB-S,QPSK
+61=11658,V,8520,23,DVB-S,QPSK
+62=11671,V,1480,34,DVB-S,QPSK
+63=11684,H,3350,78,DVB-S,QPSK
+64=11687,V,5185,34,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini
new file mode 100644
index 000000000..b1118d4fb
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3592.ini
@@ -0,0 +1,110 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3592
+2=Thor 5/6/7/Intelsat 10-02 (0.8W)
+
+[DVB]
+0=101
+1=3722,V,18000,34,S2,8PSK
+2=3977,H,17777,34,DVB-S,QPSK
+3=3985,V,9764,23,DVB-S,QPSK
+4=4025,V,7324,23,DVB-S,QPSK
+5=4032,H,1000,56,S2,8PSK
+6=4175,V,28000,34,DVB-S,QPSK
+7=10716,H,24500,78,DVB-S,QPSK
+8=10747,V,25000,34,S2,8PSK
+9=10747,H,25000,34,S2,8PSK
+10=10778,V,25000,34,S2,8PSK
+11=10778,H,24500,78,DVB-S,QPSK
+12=10809,V,24500,78,DVB-S,QPSK
+13=10809,H,24500,78,DVB-S,QPSK
+14=10841,H,25000,34,S2,8PSK
+15=10872,V,25000,34,S2,8PSK
+16=10872,H,25000,34,S2,8PSK
+17=10903,V,25000,34,S2,8PSK
+18=10903,H,25000,34,S2,8PSK
+19=10934,V,24500,78,DVB-S,QPSK
+20=10934,H,25000,34,S2,8PSK
+21=10962,H,1550,78,DVB-S,QPSK
+22=11038,H,2200,56,S2,8PSK
+23=11048,H,3100,34,DVB-S,QPSK
+24=11063,H,1500,56,S2,8PSK
+25=11080,H,1100,34,DVB-S,QPSK
+26=11104,H,3360,23,S2,8PSK
+27=11216,V,24500,78,DVB-S,QPSK
+28=11229,H,24500,78,DVB-S,QPSK
+29=11247,V,24500,78,DVB-S,QPSK
+30=11261,H,25000,34,S2,8PSK
+31=11278,V,24500,78,DVB-S,QPSK
+32=11293,H,25000,34,S2,8PSK
+33=11309,V,24500,78,DVB-S,QPSK
+34=11325,H,24500,78,DVB-S,QPSK
+35=11341,V,25000,34,S2,8PSK
+36=11357,H,24500,78,DVB-S,QPSK
+37=11372,V,24500,78,DVB-S,QPSK
+38=11389,H,24500,78,DVB-S,QPSK
+39=11403,V,24500,78,DVB-S,QPSK
+40=11421,H,24500,78,DVB-S,QPSK
+41=11461,V,4937,34,S2,8PSK
+42=11467,V,2500,34,S2,8PSK
+43=11471,V,3300,34,S2,8PSK
+44=11479,V,4936,34,S2,8PSK
+45=11489,V,6680,23,S2,8PSK
+46=11502,V,2220,34,S2,QPSK
+47=11512,V,2222,78,DVB-S,QPSK
+48=11517,V,7500,56,S2,8PSK
+49=11529,V,2222,78,DVB-S,QPSK
+50=11533,V,3600,Auto,S2,QPSK
+51=11542,V,3472,34,S2,8PSK
+52=11547,V,3472,34,S2,8PSK
+53=11554,V,6111,34,DVB-S,QPSK
+54=11559,V,3600,34,S2,8PSK
+55=11565,V,2200,34,S2,8PSK
+56=11608,H,5655,78,DVB-S,QPSK
+57=11643,H,3333,34,DVB-S,QPSK
+58=11727,V,28000,78,DVB-S,QPSK
+59=11747,H,28000,56,DVB-S,QPSK
+60=11766,V,28000,78,DVB-S,QPSK
+61=11785,H,30000,34,S2,8PSK
+62=11804,V,28000,78,DVB-S,QPSK
+63=11823,H,30000,56,S2,8PSK
+64=11843,V,30000,34,S2,8PSK
+65=11900,H,28000,56,DVB-S,QPSK
+66=11919,V,28000,78,DVB-S,QPSK
+67=11938,H,28000,78,DVB-S,QPSK
+68=11977,H,30000,34,S2,8PSK
+69=11996,V,28000,78,DVB-S,QPSK
+70=12015,H,30000,34,S2,8PSK
+71=12034,V,30000,34,S2,8PSK
+72=12054,H,30000,34,S2,8PSK
+73=12073,V,28000,78,DVB-S,QPSK
+74=12092,H,28000,78,DVB-S,QPSK
+75=12111,V,28000,78,DVB-S,QPSK
+76=12188,V,28000,78,DVB-S,QPSK
+77=12207,H,30000,34,S2,8PSK
+78=12226,V,27500,56,DVB-S,QPSK
+79=12265,V,28000,78,DVB-S,QPSK
+80=12303,V,27500,56,S2,8PSK
+81=12380,V,28000,56,DVB-S,QPSK
+82=12418,V,28000,78,DVB-S,QPSK
+83=12456,V,28000,78,DVB-S,QPSK
+84=12511,V,3300,56,S2,8PSK
+85=12515,V,3300,56,S2,8PSK
+86=12520,V,3700,56,S2,8PSK
+87=12524,V,3750,56,S2,8PSK
+88=12527,H,27500,34,DVB-S,QPSK
+89=12529,V,4750,56,S2,8PSK
+90=12535,V,5000,89,S2,8PSK
+91=12541,V,6660,56,S2,8PSK
+92=12563,H,27500,34,DVB-S,QPSK
+93=12563,V,27500,34,DVB-S,QPSK
+94=12607,H,27500,34,DVB-S,QPSK
+95=12607,V,26667,23,S2,8PSK
+96=12643,H,27500,34,DVB-S,QPSK
+97=12643,V,27500,34,DVB-S,QPSK
+98=12687,H,27500,34,DVB-S,QPSK
+99=12687,V,27500,34,DVB-S,QPSK
+100=12723,H,27500,34,DVB-S,QPSK
+101=12735,V,8800,56,DVB-S,QPSK
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini
new file mode 100644
index 000000000..f762d2f6f
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/ini/satellite/3594.ini
@@ -0,0 +1,10 @@
+; file generated on saturday, 22nd of august 2015, 19:35:09 [GMT]
+; by online transponder .ini generator @ http://satellites-xml.eu
+; please let us know if you find any inconsistencies in this file
+[SATTYPE]
+1=3594
+2=Thor 7 (0.6W)
+
+[DVB]
+0=1
+1=12207,H,30000,34,S2,8PSK
diff --git a/MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs b/MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs
deleted file mode 100644
index 14588b427..000000000
--- a/MediaBrowser.Server.Startup.Common/MbLinkShortcutHandler.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using System.IO;
-using CommonIO;
-
-namespace MediaBrowser.Server.Startup.Common
-{
- public class MbLinkShortcutHandler : IShortcutHandler
- {
- private readonly IFileSystem _fileSystem;
-
- public MbLinkShortcutHandler(IFileSystem fileSystem)
- {
- _fileSystem = fileSystem;
- }
-
- public string Extension
- {
- get { return ".mblink"; }
- }
-
- public string Resolve(string shortcutPath)
- {
- if (string.IsNullOrEmpty(shortcutPath))
- {
- throw new ArgumentNullException("filenshortcutPathame");
- }
-
- if (string.Equals(Path.GetExtension(shortcutPath), ".mblink", StringComparison.OrdinalIgnoreCase))
- {
- var path = _fileSystem.ReadAllText(shortcutPath);
-
- return _fileSystem.NormalizePath(path);
- }
-
- return null;
- }
-
- public void Create(string shortcutPath, string targetPath)
- {
- if (string.IsNullOrEmpty(shortcutPath))
- {
- throw new ArgumentNullException("shortcutPath");
- }
-
- if (string.IsNullOrEmpty(targetPath))
- {
- throw new ArgumentNullException("targetPath");
- }
-
- File.WriteAllText(shortcutPath, targetPath);
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index 3dbcaaaf4..a1bca62e0 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MediaBrowser.Server.Startup.Common</RootNamespace>
<AssemblyName>MediaBrowser.Server.Startup.Common</AssemblyName>
- <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFrameworkProfile />
@@ -22,6 +22,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>None</DebugType>
@@ -30,27 +31,19 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
- <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
+ <Reference Include="Emby.Server.Core">
+ <HintPath>..\ThirdParty\emby\Emby.Server.Core.dll</HintPath>
</Reference>
- <Reference Include="Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Mono.Posix.4.0.0.0\lib\net40\Mono.Posix.dll</HintPath>
+ <Reference Include="INIFileParser, Version=2.3.0.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
+ <HintPath>..\packages\ini-parser.2.3.0\lib\net20\INIFileParser.dll</HintPath>
+ <Private>True</Private>
</Reference>
- <Reference Include="Patterns.Logging, Version=1.0.5494.41209, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Interfaces, Version=4.0.0.0, Culture=neutral, PublicKeyToken=e06fbc6124f57c43, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
- </Reference>
- <Reference Include="ServiceStack.Text, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>
+ <Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.1\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
+ <Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
@@ -65,37 +58,68 @@
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
- <Compile Include="ApplicationHost.cs" />
<Compile Include="ApplicationPathHelper.cs" />
- <Compile Include="Browser\BrowserLauncher.cs" />
- <Compile Include="EntryPoints\KeepServerAwake.cs" />
- <Compile Include="EntryPoints\StartupWizard.cs" />
- <Compile Include="FFMpeg\FFMpegLoader.cs" />
- <Compile Include="FFMpeg\FFMpegInstallInfo.cs" />
- <Compile Include="FFMpeg\FFMpegInfo.cs" />
- <Compile Include="INativeApp.cs" />
- <Compile Include="MbLinkShortcutHandler.cs" />
- <Compile Include="Migrations\IVersionMigration.cs" />
- <Compile Include="Migrations\DbMigration.cs" />
- <Compile Include="Migrations\MovieDbEpisodeProviderMigration.cs" />
- <Compile Include="Migrations\UpdateLevelMigration.cs" />
- <Compile Include="NativeEnvironment.cs" />
+ <Compile Include="Cryptography\ASN1.cs" />
+ <Compile Include="Cryptography\ASN1Convert.cs" />
+ <Compile Include="Cryptography\BitConverterLE.cs" />
+ <Compile Include="Cryptography\CertificateGenerator.cs" />
+ <Compile Include="Cryptography\CryptoConvert.cs" />
+ <Compile Include="Cryptography\PfxGenerator.cs" />
+ <Compile Include="Cryptography\PKCS1.cs" />
+ <Compile Include="Cryptography\PKCS12.cs" />
+ <Compile Include="Cryptography\PKCS7.cs" />
+ <Compile Include="Cryptography\PKCS8.cs" />
+ <Compile Include="Cryptography\X501Name.cs" />
+ <Compile Include="Cryptography\X509Builder.cs" />
+ <Compile Include="Cryptography\X509Certificate.cs" />
+ <Compile Include="Cryptography\X509CertificateBuilder.cs" />
+ <Compile Include="Cryptography\X509CertificateCollection.cs" />
+ <Compile Include="Cryptography\X509Extension.cs" />
+ <Compile Include="Cryptography\X509Extensions.cs" />
+ <Compile Include="Cryptography\X520Attributes.cs" />
+ <Compile Include="ImageEncoderHelper.cs" />
+ <Compile Include="IO\MemoryStreamProvider.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\ReportBlock.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpAppPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpByePacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpListener.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpReceiverReportPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSenderReportPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\RtcpSourceDescriptionPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionBlock.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtcp\SourceDescriptionItem.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpListener.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtp\RtpPacket.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspMethod.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspRequest.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspResponse.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspSession.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspStatusCode.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\SatIpDiscovery.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\SatIpHost.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\TransmissionMode.cs" />
+ <Compile Include="LiveTv\TunerHosts\SatIp\Utils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="StartupOptions.cs" />
- <Compile Include="UnhandledExceptionWriter.cs" />
+ <Compile Include="SystemEvents.cs" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\Emby.Drawing.ImageMagick\Emby.Drawing.ImageMagick.csproj">
+ <Project>{6cfee013-6e7c-432b-ac37-cabf0880c69a}</Project>
+ <Name>Emby.Drawing.ImageMagick</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Emby.Drawing.Net\Emby.Drawing.Net.csproj">
+ <Project>{c97a239e-a96c-4d64-a844-ccf8cc30aecb}</Project>
+ <Name>Emby.Drawing.Net</Name>
+ </ProjectReference>
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj">
<Project>{08fff49b-f175-4807-a2b5-73b0ebd9f716}</Project>
<Name>Emby.Drawing</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj">
- <Project>{4fd51ac5-2c16-4308-a993-c3a84f3b4582}</Project>
- <Name>MediaBrowser.Api</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj">
- <Project>{c4d2573a-3fd3-441f-81af-174ac4cd4e1d}</Project>
- <Name>MediaBrowser.Common.Implementations</Name>
+ <ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">
+ <Project>{e383961b-9356-4d5d-8233-9a1079d03055}</Project>
+ <Name>Emby.Server.Implementations</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
@@ -105,42 +129,185 @@
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
<Name>MediaBrowser.Controller</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Dlna\MediaBrowser.Dlna.csproj">
- <Project>{734098eb-6dc1-4dd0-a1ca-3140dcd2737c}</Project>
- <Name>MediaBrowser.Dlna</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj">
- <Project>{7ef9f3e0-697d-42f3-a08f-19deb5f84392}</Project>
- <Name>MediaBrowser.LocalMetadata</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj">
- <Project>{0bd82fa6-eb8a-4452-8af5-74f9c3849451}</Project>
- <Name>MediaBrowser.MediaEncoding</Name>
- </ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj">
- <Project>{442b5058-dcaf-4263-bb6a-f21e31120a1b}</Project>
- <Name>MediaBrowser.Providers</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj">
- <Project>{2e781478-814d-4a48-9d80-bff206441a65}</Project>
- <Name>MediaBrowser.Server.Implementations</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj">
- <Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project>
- <Name>MediaBrowser.WebDashboard</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj">
- <Project>{23499896-b135-4527-8574-c26e926ea99e}</Project>
- <Name>MediaBrowser.XbmcMetadata</Name>
- </ProjectReference>
</ItemGroup>
<ItemGroup>
+ <None Include="app.config" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0030.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0049.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0070.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0090.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0100.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0130.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0160.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0170.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0192.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0200.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0215.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0235.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0255.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0260.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0282.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0305.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0308.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0310.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0315.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0330.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0360.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0380.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0390.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0400.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0420.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0435.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0450.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0460.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0475.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0480.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0490.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0505.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0510.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0520.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0525.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0530.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0549.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0560.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0570.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0600.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0620.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0642.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0650.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0660.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0685.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0705.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0721.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0740.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0750.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0765.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0785.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0830.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0851.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0865.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0875.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0880.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0900.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0915.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0922.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0935.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0950.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\0965.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1005.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1030.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1055.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1082.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1100.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1105.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1130.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1155.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1160.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1180.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1195.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1222.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1240.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1250.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1280.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1320.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1340.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1380.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1400.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1440.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1500.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1520.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1540.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1560.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1590.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1600 OPTUS D1 FTA %28160.0E%29.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1600.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1620.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1640.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1660.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1690.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1720.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1800.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\1830.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2210.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2230.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2250.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2270.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2290.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2310.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2330.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2350.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2370.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2390.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2410.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2432.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2451.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2470.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2489.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2500.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2527.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2550.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2570.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2590.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2608.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2630.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2650.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2669.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2690.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2710.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2728.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2730.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2750.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2760.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2770.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2780.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2812.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2820.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2830.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2850.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2873.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2880.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2881.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2882.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2900.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2930.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2950.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2970.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2985.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\2990.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3020.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3045.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3070.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3100.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3125.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3150.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3169.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3195.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3225.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3255.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3285.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3300.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3325.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3355.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3380.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3400.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3420.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3450.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3460.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3475.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3490.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3520.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3527.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3550.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3560.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3592.ini" />
+ <None Include="LiveTv\TunerHosts\SatIp\ini\satellite\3594.ini" />
<None Include="packages.config" />
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs
deleted file mode 100644
index 6bcdcca87..000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System.Threading.Tasks;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Server.Implementations.Persistence;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- public class DbMigration : IVersionMigration
- {
- private readonly IServerConfigurationManager _config;
- private readonly ITaskManager _taskManager;
-
- public DbMigration(IServerConfigurationManager config, ITaskManager taskManager)
- {
- _config = config;
- _taskManager = taskManager;
- }
-
- public async Task Run()
- {
- // If a forced migration is required, do that now
- if (_config.Configuration.MigrationVersion < CleanDatabaseScheduledTask.MigrationVersion)
- {
- if (!_config.Configuration.IsStartupWizardCompleted)
- {
- _config.Configuration.MigrationVersion = CleanDatabaseScheduledTask.MigrationVersion;
- _config.SaveConfiguration();
- return;
- }
-
- _taskManager.SuspendTriggers = true;
- CleanDatabaseScheduledTask.EnableUnavailableMessage = true;
-
- Task.Run(async () =>
- {
- await Task.Delay(1000).ConfigureAwait(false);
-
- _taskManager.Execute<CleanDatabaseScheduledTask>();
- });
-
- return;
- }
-
- if (_config.Configuration.SchemaVersion < SqliteItemRepository.LatestSchemaVersion)
- {
- if (!_config.Configuration.IsStartupWizardCompleted)
- {
- _config.Configuration.SchemaVersion = SqliteItemRepository.LatestSchemaVersion;
- _config.SaveConfiguration();
- return;
- }
-
- Task.Run(async () =>
- {
- await Task.Delay(1000).ConfigureAwait(false);
-
- _taskManager.Execute<CleanDatabaseScheduledTask>();
- });
- }
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs
deleted file mode 100644
index 6ef08fae9..000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/IVersionMigration.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- public interface IVersionMigration
- {
- Task Run();
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs
deleted file mode 100644
index cd2122e57..000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/MovieDbEpisodeProviderMigration.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using MediaBrowser.Controller.Configuration;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- class MovieDbEpisodeProviderMigration : IVersionMigration
- {
- private readonly IServerConfigurationManager _config;
- private const string _providerName = "TheMovieDb";
-
- public MovieDbEpisodeProviderMigration(IServerConfigurationManager config)
- {
- _config = config;
- }
-
- public async Task Run()
- {
- var migrationKey = this.GetType().FullName;
- var migrationKeyList = _config.Configuration.Migrations.ToList();
-
- if (!migrationKeyList.Contains(migrationKey))
- {
- foreach (var metaDataOption in _config.Configuration.MetadataOptions)
- {
- if (metaDataOption.ItemType == "Episode")
- {
- var disabledFetchers = metaDataOption.DisabledMetadataFetchers.ToList();
- if (!disabledFetchers.Contains(_providerName))
- {
- disabledFetchers.Add(_providerName);
- metaDataOption.DisabledMetadataFetchers = disabledFetchers.ToArray();
- }
- }
- }
-
- migrationKeyList.Add(migrationKey);
- _config.Configuration.Migrations = migrationKeyList.ToArray();
- _config.SaveConfiguration();
- }
-
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs
deleted file mode 100644
index 8483ca904..000000000
--- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Implementations.Updates;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Updates;
-
-namespace MediaBrowser.Server.Startup.Common.Migrations
-{
- public class UpdateLevelMigration : IVersionMigration
- {
- private readonly IServerConfigurationManager _config;
- private readonly IServerApplicationHost _appHost;
- private readonly IHttpClient _httpClient;
- private readonly IJsonSerializer _jsonSerializer;
- private readonly string _releaseAssetFilename;
- private readonly ILogger _logger;
-
- public UpdateLevelMigration(IServerConfigurationManager config, IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, string releaseAssetFilename, ILogger logger)
- {
- _config = config;
- _appHost = appHost;
- _httpClient = httpClient;
- _jsonSerializer = jsonSerializer;
- _releaseAssetFilename = releaseAssetFilename;
- _logger = logger;
- }
-
- public async Task Run()
- {
- var lastVersion = _config.Configuration.LastVersion;
- var currentVersion = _appHost.ApplicationVersion;
-
- if (string.Equals(lastVersion, currentVersion.ToString(), StringComparison.OrdinalIgnoreCase))
- {
- return;
- }
-
- try
- {
- var updateLevel = _config.Configuration.SystemUpdateLevel;
-
- await CheckVersion(currentVersion, updateLevel, CancellationToken.None).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in update migration", ex);
- }
- }
-
- private async Task CheckVersion(Version currentVersion, PackageVersionClass currentUpdateLevel, CancellationToken cancellationToken)
- {
- var releases = await new GithubUpdater(_httpClient, _jsonSerializer)
- .GetLatestReleases("MediaBrowser", "Emby", _releaseAssetFilename, cancellationToken).ConfigureAwait(false);
-
- var newUpdateLevel = GetNewUpdateLevel(currentVersion, currentUpdateLevel, releases);
-
- if (newUpdateLevel != currentUpdateLevel)
- {
- _config.Configuration.SystemUpdateLevel = newUpdateLevel;
- _config.SaveConfiguration();
- }
- }
-
- private PackageVersionClass GetNewUpdateLevel(Version currentVersion, PackageVersionClass currentUpdateLevel, List<GithubUpdater.RootObject> releases)
- {
- var newUpdateLevel = currentUpdateLevel;
-
- // If the current version is later than current stable, set the update level to beta
- if (releases.Count >= 1)
- {
- var release = releases[0];
- var version = ParseVersion(release.tag_name);
- if (version != null)
- {
- if (currentVersion > version)
- {
- newUpdateLevel = PackageVersionClass.Beta;
- }
- else
- {
- return PackageVersionClass.Release;
- }
- }
- }
-
- // If the current version is later than current beta, set the update level to dev
- if (releases.Count >= 2)
- {
- var release = releases[1];
- var version = ParseVersion(release.tag_name);
- if (version != null)
- {
- if (currentVersion > version)
- {
- newUpdateLevel = PackageVersionClass.Dev;
- }
- else
- {
- return PackageVersionClass.Beta;
- }
- }
- }
-
- return newUpdateLevel;
- }
-
- private Version ParseVersion(string versionString)
- {
- if (!string.IsNullOrWhiteSpace(versionString))
- {
- var parts = versionString.Split('.');
- if (parts.Length == 3)
- {
- versionString += ".0";
- }
- }
-
- Version version;
- Version.TryParse(versionString, out version);
-
- return version;
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs b/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs
deleted file mode 100644
index b30509982..000000000
--- a/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using MediaBrowser.Model.System;
-
-namespace MediaBrowser.Server.Startup.Common
-{
- public class NativeEnvironment
- {
- public OperatingSystem OperatingSystem { get; set; }
- public Architecture SystemArchitecture { get; set; }
- public string OperatingSystemVersionString { get; set; }
- }
-
- public enum OperatingSystem
- {
- Windows = 0,
- Osx = 1,
- Bsd = 2,
- Linux = 3
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/StartupOptions.cs b/MediaBrowser.Server.Startup.Common/StartupOptions.cs
deleted file mode 100644
index 1acaf6348..000000000
--- a/MediaBrowser.Server.Startup.Common/StartupOptions.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Server.Startup.Common
-{
- public class StartupOptions
- {
- private readonly List<string> _options = Environment.GetCommandLineArgs().ToList();
-
- public bool ContainsOption(string option)
- {
- return _options.Contains(option, StringComparer.OrdinalIgnoreCase);
- }
-
- public string GetOption(string name)
- {
- var index = _options.IndexOf(name);
-
- if (index != -1)
- {
- return _options.ElementAtOrDefault(index + 1);
- }
-
- return null;
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/SystemEvents.cs b/MediaBrowser.Server.Startup.Common/SystemEvents.cs
new file mode 100644
index 000000000..8d5cd4ad8
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/SystemEvents.cs
@@ -0,0 +1,50 @@
+using System;
+using MediaBrowser.Common.Events;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.System;
+
+namespace MediaBrowser.Server.Startup.Common
+{
+ public class SystemEvents : ISystemEvents
+ {
+ public event EventHandler Resume;
+ public event EventHandler Suspend;
+ public event EventHandler SessionLogoff;
+ public event EventHandler SystemShutdown;
+
+ private readonly ILogger _logger;
+
+ public SystemEvents(ILogger logger)
+ {
+ _logger = logger;
+ Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+ Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding;
+ }
+
+ private void SystemEvents_SessionEnding(object sender, Microsoft.Win32.SessionEndingEventArgs e)
+ {
+ switch (e.Reason)
+ {
+ case Microsoft.Win32.SessionEndReasons.Logoff:
+ EventHelper.FireEventIfNotNull(SessionLogoff, this, EventArgs.Empty, _logger);
+ break;
+ case Microsoft.Win32.SessionEndReasons.SystemShutdown:
+ EventHelper.FireEventIfNotNull(SystemShutdown, this, EventArgs.Empty, _logger);
+ break;
+ }
+ }
+
+ private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
+ {
+ switch (e.Mode)
+ {
+ case Microsoft.Win32.PowerModes.Resume:
+ EventHelper.FireEventIfNotNull(Resume, this, EventArgs.Empty, _logger);
+ break;
+ case Microsoft.Win32.PowerModes.Suspend:
+ EventHelper.FireEventIfNotNull(Suspend, this, EventArgs.Empty, _logger);
+ break;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs b/MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs
deleted file mode 100644
index 804533b9d..000000000
--- a/MediaBrowser.Server.Startup.Common/UnhandledExceptionWriter.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Implementations.Logging;
-using MediaBrowser.Model.Logging;
-using System;
-using System.IO;
-
-namespace MediaBrowser.Server.Startup.Common
-{
- public class UnhandledExceptionWriter
- {
- private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
- private readonly ILogManager _logManager;
-
- public UnhandledExceptionWriter(IApplicationPaths appPaths, ILogger logger, ILogManager logManager)
- {
- _appPaths = appPaths;
- _logger = logger;
- _logManager = logManager;
- }
-
- public void Log(Exception ex)
- {
- _logger.ErrorException("UnhandledException", ex);
- _logManager.Flush();
-
- var path = Path.Combine(_appPaths.LogDirectoryPath, "unhandled_" + Guid.NewGuid() + ".txt");
- Directory.CreateDirectory(Path.GetDirectoryName(path));
-
- var builder = LogHelper.GetLogMessage(ex);
-
- // Write to console just in case file logging fails
- Console.WriteLine("UnhandledException");
- Console.WriteLine(builder.ToString());
-
- File.WriteAllText(path, builder.ToString());
- }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/app.config b/MediaBrowser.Server.Startup.Common/app.config
new file mode 100644
index 000000000..e5b8d3d02
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/app.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/packages.config b/MediaBrowser.Server.Startup.Common/packages.config
index 238025a78..b12895000 100644
--- a/MediaBrowser.Server.Startup.Common/packages.config
+++ b/MediaBrowser.Server.Startup.Common/packages.config
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
- <package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
- <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
+ <package id="ini-parser" version="2.3.0" targetFramework="net46" />
+ <package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.1" targetFramework="net46" />
</packages> \ No newline at end of file