mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-05-07 11:07:04 +02:00
- moved all files to a "source" subdirectory to tidy up the GitHub project page
- started to write a readme.md
This commit is contained in:
31
source/ChanSort.Loader.Samsung/AnalogChannel.cs
Normal file
31
source/ChanSort.Loader.Samsung/AnalogChannel.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
internal class AnalogChannel : ScmChannelBase
|
||||
{
|
||||
private const string _Frequency = "offFrequency";
|
||||
|
||||
#region ctor()
|
||||
|
||||
public AnalogChannel(int slot, bool isCable, DataMapping mapping, decimal freq, FavoritesIndexMode sortedFavorites) :
|
||||
base(mapping, sortedFavorites)
|
||||
{
|
||||
var signalSource = SignalSource.Analog | SignalSource.Tv;
|
||||
signalSource |= isCable ? SignalSource.Cable : SignalSource.Antenna;
|
||||
this.InitCommonData(slot, signalSource, mapping);
|
||||
|
||||
var floatFreq = mapping.GetFloat(_Frequency);
|
||||
if (!float.IsNaN(floatFreq))
|
||||
this.FreqInMhz = (decimal)floatFreq; // C,D,E series have the value in the data record
|
||||
if (this.FreqInMhz == 0) // for B series take it from the Tuning table
|
||||
this.FreqInMhz = freq;
|
||||
if (this.FreqInMhz == 0) // fallback since Freq is part of the UID and requires a unique value
|
||||
this.FreqInMhz = slot;
|
||||
this.ChannelOrTransponder = "";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
123
source/ChanSort.Loader.Samsung/ChanSort.Loader.Samsung.csproj
Normal file
123
source/ChanSort.Loader.Samsung/ChanSort.Loader.Samsung.csproj
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A1C9A98D-368A-44E8-9B7F-7EACA46C9EC5}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ChanSort.Loader.Samsung</RootNamespace>
|
||||
<AssemblyName>ChanSort.Loader.Samsung</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
||||
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
|
||||
<CodeAnalysisFailOnMissingRules>true</CodeAnalysisFailOnMissingRules>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\DLL\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AnalogChannel.cs" />
|
||||
<Compile Include="DigitalChannel.cs" />
|
||||
<Compile Include="FavMode.cs" />
|
||||
<Compile Include="ModelConstants.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Resource.de.Designer.cs">
|
||||
<DependentUpon>Resource.de.resx</DependentUpon>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="Resource.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resource.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SatChannel.cs" />
|
||||
<Compile Include="SatelliteMapping.cs" />
|
||||
<Compile Include="ScmChannelBase.cs" />
|
||||
<Compile Include="ScmSerializer.cs" />
|
||||
<Compile Include="ScmSerializerPlugin.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ChanSort.Api\ChanSort.Api.csproj">
|
||||
<Project>{DCCFFA08-472B-4D17-BB90-8F513FC01392}</Project>
|
||||
<Name>ChanSort.Api</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ChanSort.Loader.Samsung.ini">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resource.de.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resource.de.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resource.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</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.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
359
source/ChanSort.Loader.Samsung/ChanSort.Loader.Samsung.ini
Normal file
359
source/ChanSort.Loader.Samsung/ChanSort.Loader.Samsung.ini
Normal file
@@ -0,0 +1,359 @@
|
||||
[Series:B]
|
||||
SatDataBase.dat = 145
|
||||
TransponderDataBase.dat = 49
|
||||
FineTune = 20
|
||||
FineTune_Digital = 28
|
||||
PTC = 12
|
||||
map-AirA = 28
|
||||
map-AirD = 248
|
||||
map-CableD = 248
|
||||
map-SateD = 144
|
||||
Favorites = 4
|
||||
|
||||
[Series:C]
|
||||
SatDataBase.dat = 145
|
||||
TransponderDataBase.dat = 45
|
||||
PTC = 12
|
||||
map-AirA = 40
|
||||
map-AirD = 292
|
||||
map-CableD = 292
|
||||
map-SateD = 144
|
||||
Favorites = 4
|
||||
|
||||
[Series:D]
|
||||
SatDataBase.dat = 145
|
||||
TransponderDataBase.dat = 45
|
||||
PTC = 12
|
||||
map-AirA = 64
|
||||
map-AirD = 320
|
||||
map-CableD = 320
|
||||
map-SateD = 172
|
||||
map-AstraHDPlusD = 212
|
||||
Favorites = 5
|
||||
SortedFavorites = 0
|
||||
|
||||
[Series:E]
|
||||
SatDataBase.dat = 145
|
||||
TransponderDataBase.dat = 45
|
||||
PTC = 12
|
||||
map-AirA = 64
|
||||
map-AirD = 320
|
||||
map-CableD = 320
|
||||
map-SateD = 168
|
||||
map-AstraHDPlusD = 212
|
||||
Favorites = 5
|
||||
SortedFavorites = 1
|
||||
|
||||
[Series:F]
|
||||
SatDataBase.dat = 145
|
||||
TransponderDataBase.dat = 45
|
||||
PTC = 12
|
||||
map-AirA = 64
|
||||
map-AirD = 320
|
||||
map-CableD = 320
|
||||
map-SateD = 168
|
||||
map-AstraHDPlusD = 212
|
||||
Favorites = 5
|
||||
SortedFavorites = 2
|
||||
|
||||
[Series:H]
|
||||
SatDataBase.dat = 145
|
||||
TransponderDataBase.dat = 45
|
||||
PTC = 12
|
||||
map-AirA = 64
|
||||
map-AirD = 320
|
||||
map-CableD = 320
|
||||
map-SateD = 168
|
||||
map-AstraHDPlusD = 212
|
||||
map-CyfraPlusD = 172
|
||||
Favorites = 5
|
||||
SortedFavorites = 2
|
||||
|
||||
[Analog:28]
|
||||
; map-AirA and map-CableA for B series
|
||||
offInUse = 0
|
||||
maskInUse = 0x02
|
||||
offProgramNr = 4
|
||||
offNameLength =
|
||||
offName = 12
|
||||
lenName = 10
|
||||
offFavorites = 26
|
||||
offChecksum = 27
|
||||
|
||||
[Analog:40]
|
||||
; map-AirA and map-CableA for C series
|
||||
offInUse = 1
|
||||
maskInUse = 0x01
|
||||
offDeleted = 2
|
||||
maskDeleted = 0x01
|
||||
offLock = 6
|
||||
maskLock = 0x01
|
||||
offTuned = 8
|
||||
maskTuned = 0x01
|
||||
offProgramNr = 9
|
||||
offSlotNr = 16
|
||||
offNameLength = 18
|
||||
offName = 20
|
||||
lenName = 10
|
||||
offFrequency = 32
|
||||
offFavorites = 38
|
||||
offChecksum = 39
|
||||
|
||||
[Analog:64]
|
||||
; map-AirA and map-CableA for D,E and F series
|
||||
offInUse = 1
|
||||
maskInUse = 0x01
|
||||
offDeleted = 2
|
||||
maskDeleted = 0x01
|
||||
offLock = 6
|
||||
maskLock = 0x01
|
||||
offTuned = 8
|
||||
maskTuned = 0x01
|
||||
offProgramNr = 9
|
||||
offSlotNr = 16
|
||||
offNameLength = 18
|
||||
offName = 20
|
||||
lenName = 10
|
||||
offFrequency = 32
|
||||
offFavorites = 36,40,44,48,52
|
||||
offChecksum = 63
|
||||
|
||||
[FineTune:20]
|
||||
offIsCable = 0
|
||||
maskIsCable = 0x01
|
||||
offSlotNr = 4
|
||||
offFrequency = 8
|
||||
|
||||
[FineTune_Digital:28]
|
||||
offIsCable = 0
|
||||
maskIsCable = 0x01
|
||||
offChannelTransponder = 4
|
||||
offFrequency = 16
|
||||
|
||||
[PTC:12]
|
||||
offFrequency = 4
|
||||
offChannelTransponder = 8
|
||||
|
||||
[ServiceProvider:108]
|
||||
offSignalSource = 0
|
||||
offIndex = 2
|
||||
offLenName = 6
|
||||
offName = 8
|
||||
|
||||
[DvbCT:248]
|
||||
; map-AirD and map-CableD for B series
|
||||
offProgramNr = 0
|
||||
offVideoPid = 2
|
||||
offPcrPid = 4
|
||||
; "Deleted"-flag is implemented in reverse by IsActive
|
||||
offIsActive = 6
|
||||
maskIsActive = 0x02
|
||||
offQam = 7
|
||||
offInUse = 8
|
||||
maskInUse = 0x80
|
||||
offServiceType = 9
|
||||
offServiceId = 10
|
||||
offOriginalNetworkId = 12
|
||||
offNetworkId = 14
|
||||
offEncrypted = 23
|
||||
maskEncrypted = 0x20
|
||||
offChannelTransponder = 26
|
||||
offLogicalProgramNr = 28
|
||||
offSymbolRate = 32
|
||||
offBouquet = 34
|
||||
offTransportStreamId = 36
|
||||
offName = 44
|
||||
lenName = 100
|
||||
offLock = 245
|
||||
maskLock = 0x01
|
||||
offFavorites = 246
|
||||
offChecksum = 247
|
||||
|
||||
[DvbCT:292]
|
||||
; map-AirD and map-CableD for C series
|
||||
offProgramNr = 0
|
||||
offVideoPid = 2
|
||||
offPcrPid = 4
|
||||
offServiceId = 6
|
||||
offDeleted = 8
|
||||
maskDeleted = 0x01
|
||||
offSignalSource = 10
|
||||
offQam = 12
|
||||
offBandwidth = 14
|
||||
offServiceType = 15
|
||||
offCodec = 16
|
||||
offHRes = 20
|
||||
offVRes = 22
|
||||
offEncrypted = 24
|
||||
maskEncrypted = 0x01
|
||||
offFrameRate = 25
|
||||
offSymbolRate = 28
|
||||
offLock = 31
|
||||
maskLock = 0x01
|
||||
offOriginalNetworkId = 32
|
||||
offNetworkId = 34
|
||||
offServiceProviderId = 40
|
||||
offChannelTransponder = 42
|
||||
offLogicalProgramNr = 44
|
||||
offTransportStreamId = 48
|
||||
offName = 64
|
||||
lenName = 100
|
||||
offShortName = 264
|
||||
lenShortName = 18
|
||||
offVideoFormat = 282
|
||||
offFavorites = 290
|
||||
offChecksum = 291
|
||||
|
||||
|
||||
[DvbCT:320]
|
||||
; map-AirD, map-CableD, Freesat for D,E and F series
|
||||
offProgramNr = 0
|
||||
offVideoPid = 2
|
||||
offPcrPid = 4
|
||||
offServiceId = 6
|
||||
offDeleted = 8
|
||||
maskDeleted = 0x01
|
||||
offSignalSource = 10
|
||||
offQam = 12
|
||||
offBandwidth = 14
|
||||
offServiceType = 15
|
||||
offCodec = 16
|
||||
offHRes = 20
|
||||
offVRes = 22
|
||||
offEncrypted = 24
|
||||
maskEncrypted = 0x01
|
||||
offFrameRate = 25
|
||||
offSymbolRate = 28
|
||||
offLock = 31
|
||||
maskLock = 0x01
|
||||
offOriginalNetworkId = 32
|
||||
offNetworkId = 34
|
||||
offServiceProviderId = 40
|
||||
offChannelTransponder = 42
|
||||
offLogicalProgramNr = 44
|
||||
offTransportStreamId = 48
|
||||
offName = 64
|
||||
lenName = 100
|
||||
offShortName = 264
|
||||
lenShortName = 18
|
||||
offVideoFormat = 282
|
||||
offFavorites = 292,296,300,304,308
|
||||
offChecksum = 319
|
||||
|
||||
[TransponderDataBase.dat:49]
|
||||
; B Series
|
||||
offMagicByte = 0
|
||||
offTransponderIndex = 1
|
||||
offSatelliteIndex = 5
|
||||
offFrequency = 9
|
||||
offSymbolRate = 17
|
||||
|
||||
[TransponderDataBase.dat:45]
|
||||
; C,D,E Series
|
||||
offMagicByte = 0
|
||||
offTransponderIndex = 1
|
||||
offSatelliteIndex = 5
|
||||
offFrequency = 9
|
||||
offSymbolRate = 13
|
||||
|
||||
[DvbS:144]
|
||||
; map-SateD for B and C Series
|
||||
offProgramNr = 0
|
||||
offVideoPid = 2
|
||||
offPcrPid = 4
|
||||
offInUse = 7
|
||||
maskInUse = 0x01
|
||||
offSignalSource = 10
|
||||
offLock = 13
|
||||
maskLock = 0x01
|
||||
offServiceType = 14
|
||||
offServiceId = 16
|
||||
offTransponderIndex = 18
|
||||
offSatelliteIndex = 20
|
||||
offTransportStreamId = 24
|
||||
offOriginalNetworkId = 28
|
||||
offHRes = 32
|
||||
offVRes = 34
|
||||
offName = 36
|
||||
lenName = 100
|
||||
offEncrypted = 136
|
||||
maskEncrypted = 0x01
|
||||
offServiceProviderId = 138
|
||||
offFavorites = 142
|
||||
offChecksum = 143
|
||||
|
||||
[DvbS:172]
|
||||
; map-SateD for D Series
|
||||
offProgramNr = 0
|
||||
offVideoPid = 2
|
||||
offPcrPid = 4
|
||||
offInUse = 7
|
||||
maskInUse = 0x01
|
||||
offSignalSource = 10
|
||||
offLock = 13
|
||||
maskLock = 0x01
|
||||
offServiceType = 14
|
||||
offServiceId = 16
|
||||
offTransponderIndex = 18
|
||||
offSatelliteIndex = 20
|
||||
offTransportStreamId = 24
|
||||
offOriginalNetworkId = 28
|
||||
offHRes = 32
|
||||
offVRes = 34
|
||||
offName = 36
|
||||
lenName = 100
|
||||
offEncrypted = 136
|
||||
maskEncrypted = 0x01
|
||||
offServiceProviderId = 138
|
||||
offFavorites = 140,144,148,152,156
|
||||
offChecksum = 171
|
||||
|
||||
[DvbS:168]
|
||||
; map-SateD for E and F Series
|
||||
offProgramNr = 0
|
||||
offVideoPid = 2
|
||||
offPcrPid = 4
|
||||
offInUse = 7
|
||||
maskInUse = 0x01
|
||||
offSignalSource = 10
|
||||
offLock = 13
|
||||
maskLock = 0x01
|
||||
offServiceType = 14
|
||||
offServiceId = 16
|
||||
offTransponderIndex = 18
|
||||
offSatelliteIndex = 20
|
||||
offTransportStreamId = 24
|
||||
offOriginalNetworkId = 28
|
||||
offHRes = 32
|
||||
offVRes = 34
|
||||
offName = 36
|
||||
offEncrypted = 136
|
||||
maskEncrypted = 0x01
|
||||
lenName = 100
|
||||
offServiceProviderId = 138
|
||||
offFavorites = 140,144,148,152,156
|
||||
offChecksum = 167
|
||||
|
||||
[AstraHDPlusD:212]
|
||||
; map-AstraHDPlusD for D, E and F Series
|
||||
offProgramNr = 0,20
|
||||
offVideoPid=2
|
||||
offPcrId=4
|
||||
offInUse = 7
|
||||
maskInUse = 0x01
|
||||
offSignalSource = 10
|
||||
offLock = 13
|
||||
maskLock = 0x01
|
||||
offServiceType = 14
|
||||
offServiceId = 16
|
||||
offTransponderIndex = 18
|
||||
; satindex is just a guess-pick of a field thats always 0001
|
||||
offSatelliteIndex = 40
|
||||
offTransportStreamId = 36
|
||||
offOriginalNetworkId = 32
|
||||
offName = 48
|
||||
lenName = 100
|
||||
offEncrypted = 180
|
||||
maskEncrypted = 0x01
|
||||
offFavorites = 184,188,192,196,200
|
||||
offChecksum = 211
|
||||
30
source/ChanSort.Loader.Samsung/DigitalChannel.cs
Normal file
30
source/ChanSort.Loader.Samsung/DigitalChannel.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
public class DigitalChannel : ScmChannelBase
|
||||
{
|
||||
private const string _ChannelOrTransponder = "offChannelTransponder";
|
||||
|
||||
public DigitalChannel(int slot, SignalSource signalSource, DataMapping data,
|
||||
IDictionary<int, decimal> transpFreq, FavoritesIndexMode sortedFavorites, IDictionary<int, string> providerNames) :
|
||||
base(data, sortedFavorites)
|
||||
{
|
||||
this.InitCommonData(slot, (SignalSource)((int)signalSource & ~(int)(SignalSource.TvAndRadio)), data);
|
||||
|
||||
if (!this.InUse || this.OldProgramNr == 0)
|
||||
return;
|
||||
|
||||
this.InitDvbData(data, providerNames);
|
||||
|
||||
int transp = data.GetByte(_ChannelOrTransponder);
|
||||
decimal freq = transpFreq.TryGet(transp);
|
||||
if (freq == 0)
|
||||
freq = transp*8 + 106; // (106 = DVB-C; DVB-T=306?)
|
||||
|
||||
this.ChannelOrTransponder = LookupData.Instance.GetDvbtTransponder(freq).ToString();
|
||||
this.FreqInMhz = freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
source/ChanSort.Loader.Samsung/FavMode.cs
Normal file
11
source/ChanSort.Loader.Samsung/FavMode.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
class FavMode
|
||||
{
|
||||
}
|
||||
}
|
||||
60
source/ChanSort.Loader.Samsung/ModelConstants.cs
Normal file
60
source/ChanSort.Loader.Samsung/ModelConstants.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
public enum FavoritesIndexMode
|
||||
{
|
||||
/// <summary>
|
||||
/// D model uses values 0 and 1
|
||||
/// </summary>
|
||||
Flag = 0,
|
||||
/// <summary>
|
||||
/// E model uses -1 for not-a-fav and 1-x for a fav program number
|
||||
/// </summary>
|
||||
IndividuallySorted = 1,
|
||||
/// <summary>
|
||||
/// some F models and H series uses -1 for not-a-fav, but expects 1-x to match the main program number
|
||||
/// </summary>
|
||||
MainProgramnrIndex = 2
|
||||
}
|
||||
|
||||
internal class ModelConstants
|
||||
{
|
||||
public readonly string series;
|
||||
public readonly int dvbsSatelliteLength;
|
||||
public readonly int dvbsTransponderLength;
|
||||
public readonly int dvbsChannelLength;
|
||||
public readonly int dvbtChannelLength;
|
||||
public readonly int avbtChannelLength;
|
||||
public readonly int hdplusChannelLength;
|
||||
public readonly int avbtFineTuneLength;
|
||||
public readonly int dvbtFineTuneLength;
|
||||
public readonly Favorites supportedFavorites;
|
||||
public readonly int ptcLength;
|
||||
public readonly int serviceProviderLength;
|
||||
public readonly FavoritesIndexMode SortedFavorites;
|
||||
public readonly int cyfraPlusChannelSize;
|
||||
|
||||
public ModelConstants(IniFile.Section iniSection)
|
||||
{
|
||||
this.series = iniSection.Name.Substring(iniSection.Name.Length - 1);
|
||||
this.avbtChannelLength = iniSection.GetInt("map-AirA");
|
||||
this.dvbtChannelLength = iniSection.GetInt("map-AirD");
|
||||
this.dvbsChannelLength = iniSection.GetInt("map-SateD");
|
||||
this.hdplusChannelLength = iniSection.GetInt("map-AstraHDPlusD");
|
||||
this.cyfraPlusChannelSize = iniSection.GetInt("map-CyfraPlusD");
|
||||
this.ptcLength = iniSection.GetInt("PTC");
|
||||
this.dvbsSatelliteLength = iniSection.GetInt("SatDataBase.dat");
|
||||
this.dvbsTransponderLength = iniSection.GetInt("TransponderDataBase.dat");
|
||||
this.avbtFineTuneLength = iniSection.GetInt("FineTune");
|
||||
this.dvbtFineTuneLength = iniSection.GetInt("FineTune_Digital");
|
||||
this.serviceProviderLength = iniSection.GetInt("ServiceProvider", 108);
|
||||
int numFavorites = iniSection.GetInt("Favorites");
|
||||
int mask = 0;
|
||||
for (int i = 0; i < numFavorites; i++)
|
||||
mask = (mask << 1) | 1;
|
||||
this.supportedFavorites = (Favorites)mask;
|
||||
this.SortedFavorites = (FavoritesIndexMode)iniSection.GetInt("SortedFavorites");
|
||||
}
|
||||
}
|
||||
}
|
||||
38
source/ChanSort.Loader.Samsung/Properties/AssemblyInfo.cs
Normal file
38
source/ChanSort.Loader.Samsung/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly:InternalsVisibleTo("Test.Loader")]
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ChanSort.Loader.Samsung")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ChanSort.Loader.Samsung")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("6f59ac5a-afba-42e3-a63e-c74793c15980")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
76
source/ChanSort.Loader.Samsung/Resource.Designer.cs
generated
Normal file
76
source/ChanSort.Loader.Samsung/Resource.Designer.cs
generated
Normal file
@@ -0,0 +1,76 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.34014
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ChanSort.Loader.Samsung {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resource {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resource() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChanSort.Loader.Samsung.Resource", typeof(Resource).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This file contains no data, all bytes in it are set to 0.
|
||||
///
|
||||
///Please make sure your USB stick is formatted as FAT32 and preferrably not larger than 4GB.
|
||||
///If that still does not work, try to reset your TV to factory defaults and run a new channel search.
|
||||
///(This might be necessary after a firmware update.).
|
||||
/// </summary>
|
||||
internal static string ScmSerializer_AllBytesInFileAreZero {
|
||||
get {
|
||||
return ResourceManager.GetString("ScmSerializer_AllBytesInFileAreZero", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
source/ChanSort.Loader.Samsung/Resource.de.Designer.cs
generated
Normal file
0
source/ChanSort.Loader.Samsung/Resource.de.Designer.cs
generated
Normal file
108
source/ChanSort.Loader.Samsung/Resource.de.resx
Normal file
108
source/ChanSort.Loader.Samsung/Resource.de.resx
Normal file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ScmSerializer_AllBytesInFileAreZero" xml:space="preserve">
|
||||
<value>Diese Datei enthält keine Daten, alle Bytes darin haben den Wert 0.
|
||||
|
||||
Bitte stellen Sie sicher, dass der USB Stick mit FAT32 formatiert ist und wenn möglich nicht größer als 4GB ist.
|
||||
Sollte es danach weiterhin nicht funktionieren, versuchen Sie bitte das Gerät auf Werkseinstellungen zurückzusetzen und einen Suchlauf durchzuführen.
|
||||
(Dies kann nach machen Firmwareupdates nötig sein, damit Export/Import wieder funktionieren.)</value>
|
||||
</data>
|
||||
</root>
|
||||
108
source/ChanSort.Loader.Samsung/Resource.resx
Normal file
108
source/ChanSort.Loader.Samsung/Resource.resx
Normal file
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ScmSerializer_AllBytesInFileAreZero" xml:space="preserve">
|
||||
<value>This file contains no data, all bytes in it are set to 0.
|
||||
|
||||
Please make sure your USB stick is formatted as FAT32 and preferrably not larger than 4GB.
|
||||
If that still does not work, try to reset your TV to factory defaults and run a new channel search.
|
||||
(This might be necessary after a firmware update.)</value>
|
||||
</data>
|
||||
</root>
|
||||
45
source/ChanSort.Loader.Samsung/SatChannel.cs
Normal file
45
source/ChanSort.Loader.Samsung/SatChannel.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
class SatChannel : ScmChannelBase
|
||||
{
|
||||
private const string _TransponderIndex = "offTransponderIndex";
|
||||
|
||||
public SatChannel(int slot, SignalSource presetList, DataMapping data, DataRoot dataRoot, FavoritesIndexMode sortedFavorites, IDictionary<int,string> providerNames) :
|
||||
base(data, sortedFavorites)
|
||||
{
|
||||
this.InitCommonData(slot, SignalSource.DvbS | presetList, data);
|
||||
if (!this.InUse)
|
||||
return;
|
||||
|
||||
this.InitDvbData(data, providerNames);
|
||||
|
||||
int transponderIndex = data.GetWord(_TransponderIndex);
|
||||
Transponder transponder = dataRoot.Transponder.TryGet(transponderIndex);
|
||||
if (transponder == null)
|
||||
{
|
||||
var list = dataRoot.GetChannelList(this.SignalSource|SignalSource.Tv);
|
||||
dataRoot.Warnings.AppendFormat("{0} channel record #{1} (Pr# {2} \"{3}\") contains invalid transponder index {4}\r\n",
|
||||
list.ShortCaption, slot, this.OldProgramNr, this.Name, transponderIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
Satellite sat = transponder.Satellite;
|
||||
this.Satellite = sat.Name;
|
||||
this.SatPosition = sat.OrbitalPosition;
|
||||
this.Polarity = transponder.Polarity;
|
||||
this.SymbolRate = transponder.SymbolRate;
|
||||
this.FreqInMhz = transponder.FrequencyInMhz;
|
||||
this.ChannelOrTransponder = "";
|
||||
}
|
||||
|
||||
public override void UpdateRawData()
|
||||
{
|
||||
if (this.NewProgramNr < 0) // "deleted" flag is currently unknown for sat channels
|
||||
this.InUse = false;
|
||||
base.UpdateRawData();
|
||||
}
|
||||
}
|
||||
}
|
||||
25
source/ChanSort.Loader.Samsung/SatelliteMapping.cs
Normal file
25
source/ChanSort.Loader.Samsung/SatelliteMapping.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
internal class SatelliteMapping
|
||||
{
|
||||
private static readonly Encoding utf16Encoding = new UnicodeEncoding(false, false);
|
||||
|
||||
private readonly byte[] data;
|
||||
public int BaseOffset;
|
||||
|
||||
public SatelliteMapping(byte[] data, int offset)
|
||||
{
|
||||
this.data = data;
|
||||
this.BaseOffset = offset;
|
||||
}
|
||||
|
||||
public byte MagicMarker { get { return data[BaseOffset]; } }
|
||||
public int SatelliteNr { get { return BitConverter.ToInt32(data, BaseOffset + 1); } }
|
||||
public string Name { get { return utf16Encoding.GetString(data, BaseOffset + 9, 128).TrimEnd('\0'); } }
|
||||
public bool IsEast { get { return BitConverter.ToInt32(data, BaseOffset + 137) != 0; } }
|
||||
public int Longitude { get { return BitConverter.ToInt32(data, BaseOffset + 141); } }
|
||||
}
|
||||
}
|
||||
201
source/ChanSort.Loader.Samsung/ScmChannelBase.cs
Normal file
201
source/ChanSort.Loader.Samsung/ScmChannelBase.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
public class ScmChannelBase : ChannelInfo
|
||||
{
|
||||
// common
|
||||
private const string _InUse = "InUse";
|
||||
private const string _ProgramNr = "offProgramNr";
|
||||
private const string _Name = "offName";
|
||||
private const string _NameLength = "offNameLength";
|
||||
private const string _ShortName = "offShortName";
|
||||
private const string _Favorites = "offFavorites";
|
||||
private const string _IsActive = "IsActive";
|
||||
private const string _Deleted = "Deleted";
|
||||
private const string _Encrypted = "Encrypted";
|
||||
private const string _Lock = "Lock";
|
||||
private const string _Checksum = "offChecksum";
|
||||
|
||||
// DVB
|
||||
private const string _ServiceId = "offServiceId";
|
||||
private const string _VideoPid = "offVideoPid";
|
||||
private const string _AudioPid = "offAudioPid";
|
||||
private const string _OriginalNetworkId = "offOriginalNetworkId";
|
||||
private const string _TransportStreamId = "offTransportStreamId";
|
||||
private const string _ServiceType = "offServiceType";
|
||||
private const string _SymbolRate = "offSymbolRate";
|
||||
private const string _ServiceProviderId = "offServiceProviderId";
|
||||
|
||||
private static readonly Encoding Utf16BigEndian = new UnicodeEncoding(true, false);
|
||||
private readonly FavoritesIndexMode sortedFavorites;
|
||||
|
||||
protected readonly DataMapping mapping;
|
||||
protected readonly byte[] rawData;
|
||||
internal readonly int baseOffset;
|
||||
|
||||
internal bool InUse { get; set; }
|
||||
|
||||
protected ScmChannelBase(DataMapping data, FavoritesIndexMode sortedFavorites)
|
||||
{
|
||||
this.mapping = data;
|
||||
this.rawData = data.Data;
|
||||
this.baseOffset = data.BaseOffset;
|
||||
this.mapping.DefaultEncoding = Utf16BigEndian;
|
||||
this.sortedFavorites = sortedFavorites;
|
||||
}
|
||||
|
||||
#region InitCommonData()
|
||||
protected void InitCommonData(int slot, SignalSource signalSource, DataMapping data)
|
||||
{
|
||||
this.InUse = data.GetFlag(_InUse, true);
|
||||
this.RecordIndex = slot;
|
||||
this.RecordOrder = slot;
|
||||
this.SignalSource = signalSource;
|
||||
this.OldProgramNr = (short)data.GetWord(_ProgramNr);
|
||||
this.Name = data.GetString(_Name, data.Settings.GetInt("lenName"));
|
||||
this.Favorites = this.ParseRawFavorites();
|
||||
this.Lock = data.GetFlag(_Lock);
|
||||
this.Encrypted = data.GetFlag(_Encrypted);
|
||||
this.IsDeleted = data.GetFlag(_Deleted, false) || !data.GetFlag(_IsActive, true);
|
||||
if (this.IsDeleted)
|
||||
this.OldProgramNr = -1;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ParseRawFavorites()
|
||||
private Favorites ParseRawFavorites()
|
||||
{
|
||||
var offsets = mapping.GetOffsets(_Favorites);
|
||||
if (offsets.Length == 1) // series B,C
|
||||
return (Favorites) mapping.GetByte(_Favorites);
|
||||
|
||||
// series D,E,F
|
||||
byte fav = 0;
|
||||
byte mask = 0x01;
|
||||
int favIndex = 0;
|
||||
foreach (int off in offsets)
|
||||
{
|
||||
int favValue = BitConverter.ToInt32(this.rawData, baseOffset + off);
|
||||
if (sortedFavorites == FavoritesIndexMode.Flag && favValue != 0)
|
||||
fav |= mask;
|
||||
else if (sortedFavorites != FavoritesIndexMode.Flag && favValue != -1)
|
||||
fav |= mask;
|
||||
if (sortedFavorites == FavoritesIndexMode.IndividuallySorted)
|
||||
this.FavIndex[favIndex] = favValue;
|
||||
mask <<= 1;
|
||||
++favIndex;
|
||||
}
|
||||
return (Favorites) fav;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region InitDvbData()
|
||||
protected void InitDvbData(DataMapping data, IDictionary<int, string> providerNames)
|
||||
{
|
||||
this.ShortName = data.GetString(_ShortName, data.Settings.GetInt("lenShortName"));
|
||||
this.ServiceId = data.GetWord(_ServiceId);
|
||||
//this.PcrPid = data.GetWord(_PcrPid);
|
||||
this.VideoPid = data.GetWord(_VideoPid);
|
||||
this.AudioPid = data.GetWord(_AudioPid);
|
||||
this.OriginalNetworkId = data.GetWord(_OriginalNetworkId);
|
||||
this.TransportStreamId = data.GetWord(_TransportStreamId);
|
||||
this.ServiceType = data.GetByte(_ServiceType);
|
||||
this.SymbolRate = data.GetWord(_SymbolRate);
|
||||
if (data.Settings.GetInt(_ServiceProviderId, -1) != -1)
|
||||
{
|
||||
int source = -1;
|
||||
if ((this.SignalSource & SignalSource.MaskProvider) == SignalSource.Freesat)
|
||||
source = 4;
|
||||
else if ((this.SignalSource & SignalSource.MaskProvider) == SignalSource.TivuSat)
|
||||
source = 6;
|
||||
else if ((this.SignalSource & SignalSource.Antenna) != 0)
|
||||
source = 0;
|
||||
else if ((this.SignalSource & SignalSource.Cable) != 0)
|
||||
source = 1;
|
||||
else if ((this.SignalSource & SignalSource.Sat) != 0)
|
||||
source = 3;
|
||||
int providerId = data.GetWord(_ServiceProviderId);
|
||||
this.Provider = providerNames.TryGet((source << 16) + providerId);
|
||||
}
|
||||
this.SignalSource |= LookupData.Instance.IsRadioOrTv(this.ServiceType);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateRawData()
|
||||
public override void UpdateRawData()
|
||||
{
|
||||
mapping.SetDataPtr(this.rawData, this.baseOffset);
|
||||
mapping.SetFlag(_InUse, this.InUse);
|
||||
if (this.NewProgramNr >= 0)
|
||||
mapping.SetWord(_ProgramNr, this.NewProgramNr);
|
||||
|
||||
if (this.IsNameModified)
|
||||
{
|
||||
int bytes = mapping.SetString(_Name, this.Name, mapping.Settings.GetInt("lenName"));
|
||||
mapping.SetByte(_NameLength, bytes);
|
||||
this.IsNameModified = false;
|
||||
}
|
||||
this.UpdateRawFavorites();
|
||||
mapping.SetFlag(_Lock, this.Lock);
|
||||
mapping.SetFlag(_Deleted, this.NewProgramNr < 0);
|
||||
mapping.SetFlag(_IsActive, this.NewProgramNr >= 0);
|
||||
this.UpdateChecksum();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region EraseRawData()
|
||||
internal virtual void EraseRawData()
|
||||
{
|
||||
int len = this.mapping.Settings.GetInt("offChecksum") + 1;
|
||||
Tools.MemSet(this.rawData, this.baseOffset, 0, len);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateRawFavorites()
|
||||
private void UpdateRawFavorites()
|
||||
{
|
||||
var offsets = mapping.GetOffsets(_Favorites);
|
||||
if (offsets.Length == 1) // series B,C
|
||||
{
|
||||
mapping.SetByte(_Favorites, (byte)this.Favorites & 0x0F);
|
||||
return;
|
||||
}
|
||||
|
||||
// series D,E,F
|
||||
byte fav = (byte)this.Favorites;
|
||||
byte mask = 0x01;
|
||||
int favIndex = 0;
|
||||
foreach (int off in offsets)
|
||||
{
|
||||
int favValue;
|
||||
if (this.sortedFavorites == FavoritesIndexMode.Flag) // D series
|
||||
favValue = (fav & mask) != 0 ? 1 : 0; // D series
|
||||
else if (this.sortedFavorites == FavoritesIndexMode.IndividuallySorted) // E series (and some F models with early firmware)
|
||||
favValue = (fav & mask) != 0 ? this.FavIndex[favIndex] : -1;
|
||||
else
|
||||
favValue = (fav & mask) != 0 ? this.NewProgramNr : -1; // F series (newer models/firmware), H series
|
||||
|
||||
Array.Copy(BitConverter.GetBytes(favValue), 0, this.rawData, baseOffset + off, 4);
|
||||
mask <<= 1;
|
||||
++favIndex;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateChecksum()
|
||||
private void UpdateChecksum()
|
||||
{
|
||||
var offChecksum = this.baseOffset + this.mapping.GetOffsets(_Checksum)[0];
|
||||
byte crc = 0;
|
||||
for (int i = this.baseOffset; i < offChecksum; i++)
|
||||
crc += this.rawData[i];
|
||||
this.rawData[offChecksum] = crc;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
723
source/ChanSort.Loader.Samsung/ScmSerializer.cs
Normal file
723
source/ChanSort.Loader.Samsung/ScmSerializer.cs
Normal file
@@ -0,0 +1,723 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using ChanSort.Api;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
class ScmSerializer : SerializerBase
|
||||
{
|
||||
private readonly Dictionary<string, ModelConstants> modelConstants = new Dictionary<string, ModelConstants>();
|
||||
private readonly MappingPool<DataMapping> analogMappings = new MappingPool<DataMapping>("Analog");
|
||||
private readonly MappingPool<DataMapping> dvbctMappings = new MappingPool<DataMapping>("DVB-C/T");
|
||||
private readonly MappingPool<DataMapping> dvbsMappings = new MappingPool<DataMapping>("DVB-S");
|
||||
private readonly MappingPool<DataMapping> hdplusMappings = new MappingPool<DataMapping>("AstraHD+");
|
||||
private readonly MappingPool<DataMapping> analogFineTuneMappings = new MappingPool<DataMapping>("FineTune");
|
||||
private readonly MappingPool<DataMapping> ptccableMappings = new MappingPool<DataMapping>("PTC");
|
||||
private readonly MappingPool<DataMapping> transponderMappings = new MappingPool<DataMapping>("TransponderDataBase");
|
||||
private readonly MappingPool<DataMapping> serviceProviderMappings = new MappingPool<DataMapping>("ServiceProvider");
|
||||
|
||||
private readonly ChannelList avbtChannels = new ChannelList(SignalSource.AnalogT|SignalSource.TvAndRadio, "Analog Air");
|
||||
private readonly ChannelList avbcChannels = new ChannelList(SignalSource.AnalogC|SignalSource.TvAndRadio, "Analog Cable");
|
||||
private readonly ChannelList avbxChannels = new ChannelList(SignalSource.AnalogCT | SignalSource.TvAndRadio, "Analog Air/Cable");
|
||||
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT | SignalSource.Tv, "Digital Air");
|
||||
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC | SignalSource.TvAndRadio, "Digital Cable");
|
||||
private readonly ChannelList dvbxChannels = new ChannelList(SignalSource.DvbCT | SignalSource.TvAndRadio, "Digital Air/Cable");
|
||||
private readonly ChannelList dvbsChannels = new ChannelList(SignalSource.DvbS | SignalSource.TvAndRadio, "Satellite");
|
||||
private readonly ChannelList primeChannels = new ChannelList(SignalSource.CablePrimeD | SignalSource.TvAndRadio, "Cable Prime");
|
||||
private readonly ChannelList hdplusChannels = new ChannelList(SignalSource.HdPlusD | SignalSource.TvAndRadio, "Astra HD+");
|
||||
private readonly ChannelList freesatChannels = new ChannelList(SignalSource.FreesatD | SignalSource.TvAndRadio, "Freesat");
|
||||
private readonly ChannelList tivusatChannels = new ChannelList(SignalSource.TivuSatD | SignalSource.TvAndRadio, "TivuSat");
|
||||
private readonly ChannelList canalDigitalChannels = new ChannelList(SignalSource.CanalDigitalSatD | SignalSource.TvAndRadio, "Canal Digital Sat");
|
||||
private readonly ChannelList digitalPlusChannels = new ChannelList(SignalSource.DigitalPlusD | SignalSource.TvAndRadio, "Canal+ Digital");
|
||||
private readonly ChannelList cyfraPlusChannels = new ChannelList(SignalSource.CyfraPlusD | SignalSource.TvAndRadio, "Cyfra+ Digital");
|
||||
|
||||
private readonly Dictionary<int, decimal> avbtFrequency = new Dictionary<int, decimal>();
|
||||
private readonly Dictionary<int, decimal> avbcFrequency = new Dictionary<int, decimal>();
|
||||
private readonly Dictionary<int, decimal> dvbcFrequency = new Dictionary<int, decimal>();
|
||||
private readonly Dictionary<int, decimal> dvbtFrequency = new Dictionary<int, decimal>();
|
||||
|
||||
private byte[] avbtFileContent;
|
||||
private byte[] avbcFileContent;
|
||||
private byte[] avbxFileContent;
|
||||
private byte[] dvbtFileContent;
|
||||
private byte[] dvbcFileContent;
|
||||
private byte[] dvbxFileContent;
|
||||
private byte[] dvbsFileContent;
|
||||
private byte[] hdplusFileContent;
|
||||
private byte[] primeFileContent;
|
||||
private byte[] freesatFileContent;
|
||||
private byte[] tivusatFileContent;
|
||||
private byte[] canalDigitalFileContent;
|
||||
private byte[] digitalPlusFileContent;
|
||||
private byte[] cyfraPlusFileContent;
|
||||
private ModelConstants c;
|
||||
private Dictionary<int, string> serviceProviderNames;
|
||||
|
||||
#region ctor()
|
||||
public ScmSerializer(string inputFile) : base(inputFile)
|
||||
{
|
||||
this.ReadConfigurationFromIniFile();
|
||||
this.Features.ChannelNameEdit = true;
|
||||
this.Features.CleanUpChannelData = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DisplayName
|
||||
public override string DisplayName { get { return "Samsung *.scm Loader"; } }
|
||||
#endregion
|
||||
|
||||
#region ReadConfigurationFromIniFile()
|
||||
private void ReadConfigurationFromIniFile()
|
||||
{
|
||||
string iniFile = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".ini");
|
||||
IniFile ini = new IniFile(iniFile);
|
||||
foreach (var section in ini.Sections)
|
||||
{
|
||||
int idx = section.Name.IndexOf(":");
|
||||
int len=0;
|
||||
if (idx >= 0)
|
||||
int.TryParse(section.Name.Substring(idx + 1), out len);
|
||||
|
||||
if (section.Name.StartsWith("Series:"))
|
||||
modelConstants.Add(section.Name, new ModelConstants(section));
|
||||
else if (section.Name.StartsWith("Analog:"))
|
||||
analogMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("DvbCT:"))
|
||||
dvbctMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("DvbS:"))
|
||||
dvbsMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("FineTune:"))
|
||||
analogFineTuneMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("AstraHDPlusD:"))
|
||||
hdplusMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("TransponderDataBase.dat:"))
|
||||
transponderMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("PTC:"))
|
||||
ptccableMappings.AddMapping(len, new DataMapping(section));
|
||||
else if (section.Name.StartsWith("ServiceProvider"))
|
||||
serviceProviderMappings.AddMapping(len, new DataMapping(section));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Load()
|
||||
public override void Load()
|
||||
{
|
||||
if (AllBytesInFileAreZero())
|
||||
return;
|
||||
using (ZipFile zip = new ZipFile(this.FileName))
|
||||
{
|
||||
DetectModelConstants(zip);
|
||||
DataRoot.SupportedFavorites = c.supportedFavorites;
|
||||
DataRoot.SortedFavorites = c.SortedFavorites == FavoritesIndexMode.IndividuallySorted;
|
||||
|
||||
ReadAnalogFineTuning(zip);
|
||||
ReadAnalogChannels(zip, "map-AirA", this.avbtChannels, out this.avbtFileContent, this.avbtFrequency);
|
||||
ReadAnalogChannels(zip, "map-CableA", this.avbcChannels, out this.avbcFileContent, this.avbcFrequency);
|
||||
ReadAnalogChannels(zip, "map-AirCableMixedA", this.avbxChannels, out this.avbxFileContent, this.avbcFrequency);
|
||||
ReadDvbTransponderFrequenciesFromPtc(zip, "PTCAIR", this.dvbtFrequency);
|
||||
ReadDvbServiceProviders(zip);
|
||||
ReadDvbctChannels(zip, "map-AirD", this.dvbtChannels, out this.dvbtFileContent, this.dvbtFrequency);
|
||||
ReadDvbTransponderFrequenciesFromPtc(zip, "PTCCABLE", this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-CableD", this.dvbcChannels, out this.dvbcFileContent, this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-AirCableMixedD", this.dvbxChannels, out this.dvbxFileContent, this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-CablePrime_D", this.primeChannels, out this.primeFileContent, this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-FreesatD", this.freesatChannels, out this.freesatFileContent, this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-TivusatD", this.tivusatChannels, out this.tivusatFileContent, this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-CanalDigitalSatD", this.canalDigitalChannels, out this.canalDigitalFileContent, this.dvbcFrequency);
|
||||
ReadDvbctChannels(zip, "map-DigitalPlusD", this.digitalPlusChannels, out this.digitalPlusFileContent, this.dvbcFrequency);
|
||||
ReadSatellites(zip);
|
||||
ReadTransponder(zip, "TransponderDataBase.dat");
|
||||
ReadTransponder(zip, "UserTransponderDataBase.dat");
|
||||
ReadDvbsChannels(zip, "map-SateD", this.dvbsChannels, out this.dvbsFileContent, c.dvbsChannelLength);
|
||||
ReadDvbsChannels(zip, "map-CyfraPlusD", this.cyfraPlusChannels, out this.cyfraPlusFileContent, c.cyfraPlusChannelSize);
|
||||
ReadAstraHdPlusChannels(zip);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region AllBytesInFileAreZero()
|
||||
private bool AllBytesInFileAreZero()
|
||||
{
|
||||
byte[] content = File.ReadAllBytes(this.FileName);
|
||||
foreach (var b in content)
|
||||
{
|
||||
if (b != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new FileLoadException(Resource.ScmSerializer_AllBytesInFileAreZero);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelConstants()
|
||||
private void DetectModelConstants(ZipFile zip)
|
||||
{
|
||||
if (DetectModelFromFileName()) return;
|
||||
if (DetectModelFromCloneInfoFile(zip)) return;
|
||||
if (DetectModelFromContentFileLengths(zip)) return;
|
||||
throw new FileLoadException("Unable to determine TV model from file content or name");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromFileName()
|
||||
private bool DetectModelFromFileName()
|
||||
{
|
||||
string file = Path.GetFileName(this.FileName)??"";
|
||||
System.Text.RegularExpressions.Regex regex =
|
||||
new System.Text.RegularExpressions.Regex("channel_list_([A-Z]{2}[0-9]{2}|BD-)([A-Z])[0-9A-Z]+_([0-9]{4}).*\\.scm");
|
||||
var match = regex.Match(file);
|
||||
if (match.Success)
|
||||
{
|
||||
string series;
|
||||
switch (match.Groups[3].Value)
|
||||
{
|
||||
case "1001": series = "C"; break;
|
||||
case "1101": series = "D"; break;
|
||||
case "1201":
|
||||
var letter = match.Groups[2].Value;
|
||||
series = match.Groups[1].Value.StartsWith("LT") ? "F" : // LTxxCxxx is actually an F-series model
|
||||
StringComparer.OrdinalIgnoreCase.Compare(letter, "E") < 0 ? "E" : // at least E sereis
|
||||
letter; // E, F, H
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (this.modelConstants.TryGetValue("Series:" + series, out this.c))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromCloneInfoFile()
|
||||
private bool DetectModelFromCloneInfoFile(ZipFile zip)
|
||||
{
|
||||
byte[] cloneInfo = ReadFileContent(zip, "CloneInfo");
|
||||
if (cloneInfo == null)
|
||||
{
|
||||
this.c = this.modelConstants["Series:B"];
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cloneInfo.Length >= 9)
|
||||
{
|
||||
char series = (char) cloneInfo[8];
|
||||
if (series == 'B') // 2013 B-series uses E/F-series format
|
||||
series = 'F';
|
||||
if (this.modelConstants.TryGetValue("Series:" + series, out this.c))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromContentFileLengths()
|
||||
private bool DetectModelFromContentFileLengths(ZipFile zip)
|
||||
{
|
||||
string[] candidates = {
|
||||
DetectModelFromAirAOrCableA(zip),
|
||||
DetectModelFromAirDOrCableD(zip),
|
||||
DetectModelFromSateD(zip),
|
||||
DetectModelFromTranspoderDatabase(zip),
|
||||
DetectModelFromAstraHdPlusD(zip)
|
||||
};
|
||||
|
||||
// note: E, F and B(2013) series use an identical format, so we only care about E here
|
||||
string validCandidates = "BCDE";
|
||||
foreach (var candidateList in candidates)
|
||||
{
|
||||
if (candidateList == null)
|
||||
continue;
|
||||
string newValidCandidats = "";
|
||||
foreach (var candidate in candidateList)
|
||||
{
|
||||
if (validCandidates.Contains(candidate))
|
||||
newValidCandidats += candidate;
|
||||
}
|
||||
validCandidates = newValidCandidats;
|
||||
}
|
||||
|
||||
if (validCandidates.Length == 0)
|
||||
return false;
|
||||
|
||||
this.modelConstants.TryGetValue("Series:" + validCandidates[0], out this.c);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromAirAOrCableA()
|
||||
private string DetectModelFromAirAOrCableA(ZipFile zip)
|
||||
{
|
||||
var entry = zip.GetEntry("map-AirA") ?? zip.GetEntry("map-CableA");
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
var candidates = "";
|
||||
if (entry.Size % 28000 == 0)
|
||||
candidates += "B";
|
||||
if (entry.Size % 40000 == 0)
|
||||
candidates += "C";
|
||||
if (entry.Size % 64000 == 0)
|
||||
candidates += "DE";
|
||||
return candidates;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromAirDOrCableD()
|
||||
private string DetectModelFromAirDOrCableD(ZipFile zip)
|
||||
{
|
||||
var entry = zip.GetEntry("map-AirD") ?? zip.GetEntry("map-CableD") ?? zip.GetEntry("map-CablePrime_D") ?? zip.GetEntry("map-FreesatD")
|
||||
?? zip.GetEntry("map-TivusatD") ?? zip.GetEntry("map-CanalDigitalSatD") ?? zip.GetEntry("map-DigitalPlusD");
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
var candidates = "";
|
||||
if (entry.Size % 248 == 0)
|
||||
candidates += "B";
|
||||
if (entry.Size % 292 == 0)
|
||||
candidates += "C";
|
||||
if (entry.Size % 320 == 0)
|
||||
candidates += "DE";
|
||||
return candidates;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromSateD()
|
||||
private string DetectModelFromSateD(ZipFile zip)
|
||||
{
|
||||
var entry = zip.GetEntry("map-SateD");
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
var candidates = "";
|
||||
if (entry.Size % 144 == 0)
|
||||
candidates += "BC";
|
||||
if (entry.Size % 172 == 0)
|
||||
candidates += "D";
|
||||
if (entry.Size % 168 == 0)
|
||||
candidates += "E";
|
||||
return candidates;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromTranspoderDatabase()
|
||||
private string DetectModelFromTranspoderDatabase(ZipFile zip)
|
||||
{
|
||||
var entry = zip.GetEntry("TransponderDatabase.dat");
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
var size = entry.Size - 4;
|
||||
var candidates = "";
|
||||
if (size%49 == 0)
|
||||
candidates += "B";
|
||||
if (size%45 == 0)
|
||||
candidates += "CDE";
|
||||
return candidates;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DetectModelFromAstraHdPlusD()
|
||||
private string DetectModelFromAstraHdPlusD(ZipFile zip)
|
||||
{
|
||||
var entry = zip.GetEntry("map-AstraHDPlusD");
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
||||
var size = entry.Size;
|
||||
string candidates = null;
|
||||
if (size % 212 == 0)
|
||||
candidates += "DE";
|
||||
return candidates;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region ReadAnalogFineTuning()
|
||||
private void ReadAnalogFineTuning(ZipFile zip)
|
||||
{
|
||||
int entrySize = c.avbtFineTuneLength;
|
||||
if (entrySize == 0)
|
||||
return;
|
||||
|
||||
byte[] data = ReadFileContent(zip, "FineTune");
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
var mapping = analogFineTuneMappings.GetMapping(c.avbtFineTuneLength);
|
||||
mapping.SetDataPtr(data, 0);
|
||||
int count = data.Length / c.avbtFineTuneLength;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
bool isCable = mapping.GetFlag("offIsCable", "maskIsCable"); // HACK: this is just a guess
|
||||
int slot = mapping.GetWord("offSlotNr");
|
||||
float freq = mapping.GetFloat("offFrequency");
|
||||
var dict = isCable ? avbcFrequency : avbtFrequency;
|
||||
dict[slot] = (decimal)freq;
|
||||
mapping.BaseOffset += c.avbtFineTuneLength;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadAnalogChannels()
|
||||
private void ReadAnalogChannels(ZipFile zip, string fileName, ChannelList list, out byte[] data, Dictionary<int,decimal> freq)
|
||||
{
|
||||
data = null;
|
||||
int entrySize = c.avbtChannelLength;
|
||||
if (entrySize == 0)
|
||||
return;
|
||||
|
||||
data = ReadFileContent(zip, fileName);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
this.DataRoot.AddChannelList(list);
|
||||
var rawChannel = analogMappings.GetMapping(entrySize);
|
||||
list.MaxChannelNameLength = rawChannel.Settings.GetInt("lenName")/2;
|
||||
rawChannel.SetDataPtr(data, 0);
|
||||
int count = data.Length / entrySize;
|
||||
|
||||
for (int slotIndex = 0; slotIndex < count; slotIndex++)
|
||||
{
|
||||
MapAnalogChannel(rawChannel, slotIndex, list, freq.TryGet(slotIndex));
|
||||
rawChannel.BaseOffset += entrySize;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MapAnalogChannel()
|
||||
private void MapAnalogChannel(DataMapping rawChannel, int slotIndex, ChannelList list, decimal freq)
|
||||
{
|
||||
bool isCable = (list.SignalSource & SignalSource.Cable) != 0;
|
||||
AnalogChannel ci = new AnalogChannel(slotIndex, isCable, rawChannel, freq, c.SortedFavorites);
|
||||
if (!ci.InUse)
|
||||
return;
|
||||
|
||||
this.DataRoot.AddChannel(list, ci);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region ReadDvbTransponderFrequenciesFromPtc()
|
||||
private void ReadDvbTransponderFrequenciesFromPtc(ZipFile zip, string file, IDictionary<int, decimal> table)
|
||||
{
|
||||
byte[] data = ReadFileContent(zip, file);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
var mapping = ptccableMappings.GetMapping(c.ptcLength);
|
||||
mapping.SetDataPtr(data, 0);
|
||||
int count = data.Length / c.ptcLength;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int transp = mapping.GetWord("offChannelTransponder");
|
||||
float freq = mapping.GetFloat("offFrequency");
|
||||
table[transp] = (decimal)freq;
|
||||
mapping.BaseOffset += c.ptcLength;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadDvbServiceProviders()
|
||||
private void ReadDvbServiceProviders(ZipFile zip)
|
||||
{
|
||||
this.serviceProviderNames = new Dictionary<int, string>();
|
||||
var data = ReadFileContent(zip, "ServiceProviders");
|
||||
if (data == null) return;
|
||||
|
||||
if (data.Length % c.serviceProviderLength != 0) return;
|
||||
var mapping = serviceProviderMappings.GetMapping(c.serviceProviderLength, false);
|
||||
if (mapping == null) return;
|
||||
int count = data.Length/c.serviceProviderLength;
|
||||
var enc = new UnicodeEncoding(true, false);
|
||||
var offName = mapping.Settings.GetInt("offName");
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
mapping.SetDataPtr(data, i*c.serviceProviderLength);
|
||||
int source = mapping.GetWord("offSignalSource");
|
||||
int index = mapping.GetWord("offIndex");
|
||||
int len = System.Math.Min(mapping.GetWord("offLenName"), c.serviceProviderLength - offName);
|
||||
var name = len < 2 ? "" : enc.GetString(data, mapping.BaseOffset + offName, len);
|
||||
this.serviceProviderNames[(source << 16) + index] = name;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadDvbctChannels()
|
||||
private void ReadDvbctChannels(ZipFile zip, string fileName, ChannelList list, out byte[] data, Dictionary<int, decimal> frequency)
|
||||
{
|
||||
data = null;
|
||||
int entrySize = c.dvbtChannelLength;
|
||||
if (entrySize == 0)
|
||||
return;
|
||||
|
||||
data = ReadFileContent(zip, fileName);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
this.DataRoot.AddChannelList(list);
|
||||
var source = list.SignalSource;
|
||||
DataMapping rawChannel = dvbctMappings.GetMapping(entrySize);
|
||||
list.MaxChannelNameLength = rawChannel.Settings.GetInt("lenName") / 2;
|
||||
rawChannel.SetDataPtr(data, 0);
|
||||
int count = data.Length / entrySize;
|
||||
for (int slotIndex = 0; slotIndex < count; slotIndex++)
|
||||
{
|
||||
DigitalChannel ci = new DigitalChannel(slotIndex, source, rawChannel, frequency, c.SortedFavorites, this.serviceProviderNames);
|
||||
if (ci.InUse && !ci.IsDeleted && ci.OldProgramNr > 0)
|
||||
this.DataRoot.AddChannel(list, ci);
|
||||
|
||||
rawChannel.BaseOffset += entrySize;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region ReadSatellites()
|
||||
private void ReadSatellites(ZipFile zip)
|
||||
{
|
||||
byte[] data = ReadFileContent(zip, "SatDataBase.dat");
|
||||
if (data == null || data.Length < 4)
|
||||
return;
|
||||
|
||||
this.SatDatabaseVersion = System.BitConverter.ToInt32(data, 0);
|
||||
SatelliteMapping satMapping = new SatelliteMapping(data, 4);
|
||||
int count = data.Length/this.c.dvbsSatelliteLength;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (satMapping.MagicMarker == 'U')
|
||||
{
|
||||
string location = string.Format("{0}.{1}{2}",
|
||||
satMapping.Longitude / 10, satMapping.Longitude % 10, satMapping.IsEast ? "E" : "W");
|
||||
|
||||
Satellite satellite = new Satellite(satMapping.SatelliteNr);
|
||||
satellite.Name = satMapping.Name;
|
||||
satellite.OrbitalPosition = location;
|
||||
this.DataRoot.Satellites.Add(satMapping.SatelliteNr, satellite);
|
||||
}
|
||||
else if (satMapping.MagicMarker != 'E')
|
||||
throw new FileLoadException("Unknown SatDataBase.dat format");
|
||||
|
||||
satMapping.BaseOffset += this.c.dvbsSatelliteLength;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadTransponder()
|
||||
|
||||
private void ReadTransponder(ZipFile zip, string fileName)
|
||||
{
|
||||
byte[] data = ReadFileContent(zip, fileName);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
int count = (data.Length-4)/c.dvbsTransponderLength;
|
||||
var mapping = this.transponderMappings.GetMapping(c.dvbsTransponderLength);
|
||||
for (int i=0; i<count; i++)
|
||||
{
|
||||
mapping.SetDataPtr(data, 4 + i * c.dvbsTransponderLength);
|
||||
if (mapping.GetByte("offMagicByte") == 0)
|
||||
continue;
|
||||
|
||||
int transponderNr = (int)mapping.GetDword("offTransponderIndex");
|
||||
if (transponderNr == 0)
|
||||
continue;
|
||||
|
||||
int satelliteNr = (int)mapping.GetDword("offSatelliteIndex");
|
||||
var sat = this.DataRoot.Satellites.TryGet(satelliteNr);
|
||||
if (sat == null)
|
||||
{
|
||||
DataRoot.Warnings.Append(string.Format("Transponder #{0} references invalid satellite #{1}",
|
||||
transponderNr, satelliteNr));
|
||||
continue;
|
||||
}
|
||||
Transponder transponder = new Transponder(transponderNr);
|
||||
transponder.FrequencyInMhz = (uint)(mapping.GetDword("offFrequency")/1000);
|
||||
transponder.SymbolRate = (int) (mapping.GetDword("offSymbolRate")/1000);
|
||||
this.DataRoot.AddTransponder(sat, transponder);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadDvbsChannels()
|
||||
private void ReadDvbsChannels(ZipFile zip, string filename, ChannelList channels, out byte[] fileContent, int entrySize)
|
||||
{
|
||||
fileContent = ReadFileContent(zip, filename);
|
||||
if (fileContent == null)
|
||||
return;
|
||||
|
||||
this.DataRoot.AddChannelList(channels);
|
||||
int count = fileContent.Length/entrySize;
|
||||
DataMapping mapping = dvbsMappings.GetMapping(entrySize);
|
||||
channels.MaxChannelNameLength = mapping.Settings.GetInt("lenName") / 2;
|
||||
mapping.SetDataPtr(fileContent, 0);
|
||||
for (int slotIndex = 0; slotIndex < count; slotIndex++)
|
||||
{
|
||||
SatChannel ci = new SatChannel(slotIndex, channels.SignalSource, mapping, this.DataRoot, c.SortedFavorites, this.serviceProviderNames);
|
||||
if (ci.InUse)
|
||||
this.DataRoot.AddChannel(channels, ci);
|
||||
|
||||
mapping.BaseOffset += entrySize;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadAstraHdPlusChannels()
|
||||
private void ReadAstraHdPlusChannels(ZipFile zip)
|
||||
{
|
||||
this.hdplusFileContent = ReadFileContent(zip, "map-AstraHDPlusD");
|
||||
if (hdplusFileContent == null || c.hdplusChannelLength == 0)
|
||||
return;
|
||||
|
||||
this.DataRoot.AddChannelList(this.hdplusChannels);
|
||||
int entrySize = c.hdplusChannelLength;
|
||||
int count = hdplusFileContent.Length / entrySize;
|
||||
DataMapping mapping = hdplusMappings.GetMapping(entrySize);
|
||||
mapping.SetDataPtr(hdplusFileContent, 0);
|
||||
for (int slotIndex = 0; slotIndex < count; slotIndex++)
|
||||
{
|
||||
SatChannel ci = new SatChannel(slotIndex, SignalSource.AstraHdPlus, mapping, this.DataRoot, c.SortedFavorites, this.serviceProviderNames);
|
||||
if (ci.InUse)
|
||||
this.DataRoot.AddChannel(this.hdplusChannels, ci);
|
||||
mapping.BaseOffset += entrySize;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region ReadFileContent()
|
||||
private static byte[] ReadFileContent(ZipFile zip, string fileName)
|
||||
{
|
||||
var entry = zip.GetEntry(fileName);
|
||||
if (entry == null)
|
||||
return null;
|
||||
byte[] data = new byte[entry.Size];
|
||||
using (var stream = zip.GetInputStream(entry))
|
||||
{
|
||||
stream.Read(data, 0, data.Length);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Save()
|
||||
public override void Save(string tvOutputFile)
|
||||
{
|
||||
if (tvOutputFile != this.FileName)
|
||||
{
|
||||
File.Copy(this.FileName, tvOutputFile, true);
|
||||
this.FileName = tvOutputFile;
|
||||
}
|
||||
using (ZipFile zip = new ZipFile(tvOutputFile))
|
||||
{
|
||||
zip.BeginUpdate();
|
||||
this.SaveChannels(zip, "map-AirA", this.avbtChannels, this.avbtFileContent);
|
||||
this.SaveChannels(zip, "map-CableA", this.avbcChannels, this.avbcFileContent);
|
||||
this.SaveChannels(zip, "map-AirCableMixedA", this.avbxChannels, this.avbxFileContent);
|
||||
this.SaveChannels(zip, "map-AirD", this.dvbtChannels, this.dvbtFileContent);
|
||||
this.SaveChannels(zip, "map-CableD", this.dvbcChannels, this.dvbcFileContent);
|
||||
this.SaveChannels(zip, "map-AirCableMixedD", this.dvbxChannels, this.dvbxFileContent);
|
||||
this.SaveChannels(zip, "map-SateD", this.dvbsChannels, this.dvbsFileContent);
|
||||
this.SaveChannels(zip, "map-AstraHDPlusD", this.hdplusChannels, this.hdplusFileContent);
|
||||
this.SaveChannels(zip, "map-CablePrime_D", this.primeChannels, this.primeFileContent);
|
||||
this.SaveChannels(zip, "map-FreesatD", this.freesatChannels, this.freesatFileContent);
|
||||
this.SaveChannels(zip, "map-TivusatD", this.tivusatChannels, this.tivusatFileContent);
|
||||
this.SaveChannels(zip, "map-CanalDigitalSatD", this.canalDigitalChannels, this.canalDigitalFileContent);
|
||||
this.SaveChannels(zip, "map-DigitalPlusD", this.digitalPlusChannels, this.digitalPlusFileContent);
|
||||
this.SaveChannels(zip, "map-CyfraPlusD", this.cyfraPlusChannels, this.cyfraPlusFileContent);
|
||||
zip.CommitUpdate();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SaveChannels()
|
||||
private void SaveChannels(ZipFile zip, string fileName, ChannelList channels, byte[] fileContent)
|
||||
{
|
||||
if (fileContent == null)
|
||||
return;
|
||||
zip.Delete(fileName);
|
||||
|
||||
string tempFilePath = Path.GetTempFileName();
|
||||
using (var stream = new FileStream(tempFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
|
||||
{
|
||||
this.WriteChannels(channels, fileContent, stream);
|
||||
}
|
||||
|
||||
zip.Add(tempFilePath, fileName);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteChannels()
|
||||
private void WriteChannels(ChannelList list, byte[] fileContent, FileStream stream)
|
||||
{
|
||||
foreach (var channel in list.Channels)
|
||||
{
|
||||
channel.UpdateRawData();
|
||||
channel.OldProgramNr = channel.NewProgramNr;
|
||||
}
|
||||
|
||||
stream.Write(fileContent, 0, fileContent.Length);
|
||||
}
|
||||
#endregion
|
||||
|
||||
// -------- cleanup --------
|
||||
|
||||
#region CleanUpChannelData()
|
||||
public override string CleanUpChannelData()
|
||||
{
|
||||
StringBuilder log = new StringBuilder();
|
||||
RemoveChannelsWithServiceType0(log);
|
||||
RemoveDuplicateAnalogList(log);
|
||||
return log.ToString();
|
||||
}
|
||||
|
||||
private void RemoveChannelsWithServiceType0(StringBuilder log)
|
||||
{
|
||||
foreach (var list in this.DataRoot.ChannelLists)
|
||||
{
|
||||
if ((list.SignalSource & SignalSource.Digital) == 0)
|
||||
continue;
|
||||
var listOfChannels = new List<ChannelInfo>(list.Channels);
|
||||
foreach (var chan in listOfChannels)
|
||||
{
|
||||
ScmChannelBase channel = chan as ScmChannelBase;
|
||||
if (channel == null) // ignore proxy channels (which only exist in loaded reference list)
|
||||
continue;
|
||||
if (channel.ServiceType == 0)
|
||||
{
|
||||
channel.EraseRawData();
|
||||
list.Channels.Remove(channel);
|
||||
log.AppendFormat("{0} channel at index {1} (Pr# {2} \"{3}\") was erased due to invalid service type 0\r\n",
|
||||
list.ShortCaption, channel.RecordIndex, channel.OldProgramNr, channel.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveDuplicateAnalogList(StringBuilder log)
|
||||
{
|
||||
if (this.avbtChannels.Count == 0 || this.avbcChannels.Count == 0)
|
||||
return;
|
||||
// TODO
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// ------- testing -----------
|
||||
|
||||
internal string Series { get { return c.series; } }
|
||||
internal int AnalogChannelLength { get { return c.avbtChannelLength; } }
|
||||
internal int DigitalChannelLength { get { return c.dvbtChannelLength; } }
|
||||
internal int SatChannelLength { get { return c.dvbsChannelLength; } }
|
||||
internal int HdPlusChannelLength { get { return c.hdplusChannelLength; } }
|
||||
internal int SatDatabaseVersion { get; private set; }
|
||||
}
|
||||
}
|
||||
15
source/ChanSort.Loader.Samsung/ScmSerializerPlugin.cs
Normal file
15
source/ChanSort.Loader.Samsung/ScmSerializerPlugin.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Samsung
|
||||
{
|
||||
public class ScmSerializerPlugin : ISerializerPlugin
|
||||
{
|
||||
public string PluginName { get { return "Samsung *.scm"; } }
|
||||
public string FileFilter { get { return "*.scm"; } }
|
||||
|
||||
public SerializerBase CreateSerializer(string inputFile)
|
||||
{
|
||||
return new ScmSerializer(inputFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user