- complete rework of TLL and SCM loaders, removing all "unsafe" code

- fixed various issues with SCM files
This commit is contained in:
hbeham
2013-04-03 12:47:24 +02:00
parent e194ff983b
commit 994235e020
78 changed files with 4896 additions and 2961 deletions

View File

@@ -1,219 +0,0 @@
using System.Collections.Generic;
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.TllFile
{
#region class ActChannelDataMapping
/// <summary>
/// Mapping for Analog, Cable and Terrestrial
/// </summary>
public unsafe class ActChannelDataMapping : DvbChannelMappingBase
{
private readonly DvbStringDecoder dvbsStringDecoder;
private const string offFrequencyLong = "offFrequencyLong";
private const string offFavorites2 = "offFavorites2";
private const string offProgramNr2 = "offProgramNr2";
#region ctor()
public ActChannelDataMapping(IniFile.Section settings, int length, DvbStringDecoder dvbsStringDecoder) : base(settings, length, null)
{
this.dvbsStringDecoder = dvbsStringDecoder;
this.ReorderChannelData = settings.GetInt("reorderChannelData") != 0;
}
#endregion
#region Encoding
public Encoding Encoding
{
get { return this.dvbsStringDecoder.DefaultEncoding; }
set { this.dvbsStringDecoder.DefaultEncoding = value; }
}
#endregion
public bool ReorderChannelData { get; private set; }
#region Favorites
public override Favorites Favorites
{
get { return (Favorites)(this.GetByte(offFavorites) & 0x0F); }
set
{
int intValue = (int)value;
foreach (int off in this.GetOffsets(offFavorites))
this.DataPtr[off] = (byte) ((this.DataPtr[off] & 0xF0) | intValue);
intValue <<= 2;
foreach (int off in this.GetOffsets(offFavorites2))
this.DataPtr[off] = (byte)((this.DataPtr[off] & 0xC3) | intValue);
}
}
#endregion
#region ProgramNr
public override ushort ProgramNr
{
get { return base.ProgramNr; }
set
{
base.ProgramNr = value;
this.SetWord(offProgramNr2, (ushort)((value<<2) | (GetWord(offProgramNr2) & 0x03)));
}
}
#endregion
#region Name
public override string Name
{
get
{
string longName, shortName;
this.dvbsStringDecoder.GetChannelNames(this.NamePtr, this.NameLength, out longName, out shortName);
return longName;
}
set { ChannelDataMapping.SetChannelName(this, value, this.dvbsStringDecoder.DefaultEncoding); }
}
#endregion
#region ShortName
public override string ShortName
{
get
{
string longName, shortName;
this.dvbsStringDecoder.GetChannelNames(this.NamePtr, this.NameLength, out longName, out shortName);
return shortName;
}
}
#endregion
#region FrequencyLong
public virtual uint FrequencyLong
{
get { return this.GetDword(offFrequencyLong); }
set { this.SetDword(offFrequencyLong, value); }
}
#endregion
#region AnalogFrequency, AnalogChannelNr, AnalogChannelBand
public ushort AnalogFrequency
{
get { return this.PcrPid; }
set { this.PcrPid = value; }
}
public byte AnalogChannelNr
{
get { return (byte)(this.VideoPid & 0xFF); }
}
public byte AnalogChannelBand
{
get { return (byte)(this.VideoPid >> 8); }
}
#endregion
#region Validate()
public string Validate()
{
bool ok = true;
List<string> warnings = new List<string>();
ok &= ValidateByte(offChannelTransponder) || AddWarning(warnings, "Channel/Transponder number");
ok &= ValidateWord(offProgramNr) || AddWarning(warnings, "Program#");
ok &= ValidateByte(offFavorites) || AddWarning(warnings, "Favorites");
ok &= ValidateWord(offPcrPid) || AddWarning(warnings, "PCR-PID");
ok &= ValidateWord(offAudioPid) || AddWarning(warnings, "Audio-PID");
ok &= ValidateWord(offVideoPid) || AddWarning(warnings, "Video-PID");
ok &= ValidateString(offName, 40) || AddWarning(warnings, "Channel name");
ok &= ValidateByte(offNameLength) || AddWarning(warnings, "Channel name length");
ok &= ValidateWord(offServiceId) || AddWarning(warnings, "Service-ID");
ok &= ValidateString(offFrequencyLong, 4) || AddWarning(warnings, "Frequency");
ok &= ValidateWord(offOriginalNetworkId) || AddWarning(warnings, "Original Network-ID");
ok &= ValidateWord(offTransportStreamId) || AddWarning(warnings, "Transport Stream ID");
ok &= ValidateByte(offFavorites2) || AddWarning(warnings, "Favorites #2");
ok &= ValidateByte(offServiceType) || AddWarning(warnings, "Service Type");
if (ok)
return null;
StringBuilder sb = new StringBuilder();
foreach (var warning in warnings)
{
if (sb.Length > 0)
sb.Append(", ");
sb.Append(warning);
}
return sb.ToString();
}
#endregion
#region AddWarning()
private bool AddWarning(List<string> warnings, string p)
{
warnings.Add(p);
return false;
}
#endregion
#region ValidateByte()
private bool ValidateByte(string key)
{
var offsets = this.GetOffsets(key);
if (offsets == null || offsets.Length < 1)
return true;
byte value = *(this.DataPtr + offsets[0]);
bool ok = true;
foreach(int offset in offsets)
{
if (this.DataPtr[offset] != value)
ok = false;
}
return ok;
}
#endregion
#region ValidateWord()
private bool ValidateWord(string key)
{
var offsets = this.GetOffsets(key);
if (offsets == null || offsets.Length < 1)
return true;
ushort value = *(ushort*)(this.DataPtr + offsets[0]);
bool ok = true;
foreach (int offset in offsets)
{
if (*(ushort*) (this.DataPtr + offset) != value)
ok = false;
}
return ok;
}
#endregion
#region ValidateString()
private bool ValidateString(string key, int len)
{
var offsets = this.GetOffsets(key);
if (offsets == null || offsets.Length < 1)
return true;
bool ok = true;
int off0 = offsets[0];
for (int i = 1; i < offsets.Length; i++)
{
int offI = offsets[i];
for (int j = 0; j < len; j++)
{
byte b = this.DataPtr[off0 + j];
if (this.DataPtr[offI + j] != b)
ok = false;
if (b == 0)
break;
}
}
return ok;
}
#endregion
}
#endregion
}

View File

@@ -0,0 +1,19 @@
using ChanSort.Api;
namespace ChanSort.Loader.TllFile
{
public class AnalogChannel : TllChannelBase
{
private const string _Freqency = "offPcrPid";
private const string _FreqBand = "offVideoPid";
public AnalogChannel(int slot, DataMapping data) : base(data)
{
this.InitCommonData(slot, SignalSource.AnalogCT, data);
this.FreqInMhz = (decimal)data.GetWord(_Freqency) / 20;
int channelAndBand = data.GetWord(_FreqBand);
this.ChannelOrTransponder = ((channelAndBand>>8) == 0 ? "E" : "S") + (channelAndBand&0xFF).ToString("d2");
}
}
}

View File

@@ -8,8 +8,8 @@
<ProjectGuid>{E972D8A1-2F5F-421C-AC91-CFF45E5191BE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ChanSort.Plugin.TllFile</RootNamespace>
<AssemblyName>ChanSort.Plugin.TllFile</AssemblyName>
<RootNamespace>ChanSort.Loader.TllFile</RootNamespace>
<AssemblyName>ChanSort.Loader.TllFile</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
@@ -36,7 +36,7 @@
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
@@ -68,11 +68,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ActChannelDataMapping.cs" />
<Compile Include="ChannelDataMapping.cs" />
<Compile Include="DvbsChannelDataMapping.cs" />
<Compile Include="FirmwareDataMapping.cs" />
<Compile Include="ModelConstants.cs" />
<Compile Include="AnalogChannel.cs" />
<Compile Include="DtvChannel.cs" />
<Compile Include="DvbsDataLayout.cs" />
<Compile Include="FirmwareData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resource.de.Designer.cs">
<AutoGen>True</AutoGen>
@@ -84,10 +83,13 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resource.resx</DependentUpon>
</Compile>
<Compile Include="SatChannel.cs" />
<Compile Include="SatChannelListHeader.cs" />
<Compile Include="SatTransponder.cs" />
<Compile Include="TllChannelBase.cs" />
<Compile Include="TllFileSerializer.cs" />
<Compile Include="TllFileSerializer.sql.cs" />
<Compile Include="TllFileSerializerPlugin.cs" />
<Compile Include="TllStructures.cs" />
<Compile Include="TvSettingsForm.cs">
<SubType>Form</SubType>
</Compile>

View File

@@ -1,35 +1,6 @@
; FileConfigurationX: overall file and DVB-S data layout
; ACTChannelDataMappingX: analog, DVB-C and DVB-T channel data mapping for data length X
[FileConfiguration1]
; LM and PM series except LM611S and LM340S
magicBytes = 90, 90, 90, 90
satCount = 64
satLength = 44
transponderCount = 2400
transponderLength = 40
dvbsChannelCount = 7520
dvbsChannelLength = 72
lnbCount = 40
lnbLength = 44
[FileConfiguration2]
; LV and LW series (some LW don't have DVB-S though), some LM models
magicBytes = 90, 90, 90, 90
satCount = 64
satLength = 44
transponderCount = 2400
transponderLength = 40
dvbsChannelCount = 7520
dvbsChannelLength = 68
lnbCount = 40
lnbLength = 44
[FileConfiguration3]
; DM and LH series
magicBytes =
satCount = 0
[ACTChannelDataMapping:192]
; LM series with Firmware 4.x (all except LM611S and LM340S)
@@ -48,6 +19,8 @@
offOriginalNetworkId = 102
offTransportStreamId = 104
offFavorites2 = 134
offDeleted = 134
maskDeleted = 0x42
offLock = 135
maskLock = 0x01
offSkip = 135
@@ -74,6 +47,8 @@
offOriginalNetworkId = 102
offTransportStreamId = 104
offFavorites2 = 134
offDeleted = 134
maskDeleted = 0x42
offLock = 135
maskLock = 0x01
offSkip = 135
@@ -101,6 +76,8 @@
offOriginalNetworkId = 98
offTransportStreamId = 100
offFavorites2 = 130
offDeleted = 130
maskDeleted = 0x42
offLock = 131
maskLock = 0x01
offSkip = 131
@@ -128,6 +105,8 @@
offTransportStreamId = 100
offProgramNr2 = 120
offFavorites2 = 126
offDeleted = 126
maskDeleted = 0x42
offLock = 127
maskLock = 0x01
offSkip = 127
@@ -155,6 +134,8 @@
offTransportStreamId = 96
offProgramNr2 = 116
offFavorites2 = 122
offDeleted = 122
maskDeleted = 0x42
offLock = 123
maskLock = 0x01
offSkip = 123
@@ -182,6 +163,8 @@
offFrequencyLong = 96
offProgramNr2 = 108
offFavorites2 = 113
offDeleted = 113
maskDeleted = 0x42
offLock = 113
maskLock =
offSkip = 113
@@ -191,6 +174,28 @@
offServiceType = 115
offAudioPid2 = 158
[DvbsBlock:687880]
; everything before LM series (but including LM611S and LM340S)
satCount = 64
satLength = 44
transponderCount = 2400
transponderLength = 40
dvbsChannelCount = 7520
dvbsChannelLength = 68
lnbCount = 40
lnbLength = 44
[DvbsBlock:717960]
; LM and PM series except LM611S and LM340S
satCount = 64
satLength = 44
transponderCount = 2400
transponderLength = 40
dvbsChannelCount = 7520
dvbsChannelLength = 72
lnbCount = 40
lnbLength = 44
[SatChannelDataMapping:68]
lenName = 40
offSatelliteNr = 0
@@ -198,8 +203,7 @@
offTransponderIndex = 5, 12
offProgramNr = 8
offProgramNrPreset = 10
offFavorites = 14
maskFavorites = 0x3C
offFavorites2 = 14
offDeleted = 14
maskDeleted = 0x42
offEncrypted = 14
@@ -226,8 +230,7 @@
offTransponderIndex = 6, 12
offProgramNr = 8
offProgramNrPreset = 10
offFavorites = 14
maskFavorites = 0x3C
offFavorites2 = 14
offDeleted = 14
maskDeleted = 0x42
offEncrypted = 14

View File

@@ -1,23 +0,0 @@
using System;
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.TllFile
{
internal static class ChannelDataMapping
{
public static unsafe void SetChannelName(ChannelMappingBase mapping, string channelName, Encoding defaultEncoding)
{
byte[] codePagePrefix = new byte[0]; // DvbStringDecoder.GetCodepageBytes(defaultEncoding);
byte[] name = defaultEncoding.GetBytes(channelName);
byte[] newName = new byte[codePagePrefix.Length + name.Length + 1];
Array.Copy(codePagePrefix, 0, newName, 0, codePagePrefix.Length);
Array.Copy(name, 0, newName, codePagePrefix.Length, name.Length);
fixed (byte* ptrNewName = newName)
{
mapping.NamePtr = ptrNewName;
}
mapping.NameLength = newName.Length;
}
}
}

View File

@@ -0,0 +1,24 @@
using ChanSort.Api;
namespace ChanSort.Loader.TllFile
{
public class DtvChannel : TllChannelBase
{
private const string _ChannelOrTransponder = "offChannelTransponder";
private const string _FrequencyLong = "offFrequencyLong";
/*
offFavorites2 = 134
offAudioPid2 = 182
*/
public DtvChannel(int slot, DataMapping data) : base(data)
{
this.InitCommonData(slot, SignalSource.DvbCT, data);
this.InitDvbData(data);
this.ChannelOrTransponder = data.GetByte(_ChannelOrTransponder).ToString("d2");
this.FreqInMhz = (decimal)data.GetDword(_FrequencyLong) / 1000;
}
}
}

View File

@@ -1,197 +0,0 @@
using System.Collections.Generic;
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.TllFile
{
public unsafe class DvbsChannelDataMapping : DvbChannelMappingBase
{
private const string offSatelliteNr = "offSatelliteNr";
private const string offTransponderIndex = "offTransponderIndex";
private const string offProgramNrPreset = "offProgramNrPreset";
private const string offProgNrCustomized = "offProgNrCustomized";
private const string maskProgNrCustomized = "maskProgNrCustomized";
private readonly DvbStringDecoder dvbsStringDecoder;
public DvbsChannelDataMapping(IniFile.Section settings, int dataLength, DvbStringDecoder dvbsStringDecoder) :
base(settings, dataLength, null)
{
this.dvbsStringDecoder = dvbsStringDecoder;
}
#region Encoding
public Encoding Encoding
{
get { return this.dvbsStringDecoder.DefaultEncoding; }
set { this.dvbsStringDecoder.DefaultEncoding = value; }
}
#endregion
#region InUse
public override bool InUse
{
get { return this.SatelliteNr != 0xFFFF; }
}
#endregion
#region IsDeleted
public override bool IsDeleted
{
get { return base.IsDeleted; }
set
{
base.IsDeleted = value;
if (value)
this.SatelliteNr = 0xFFFF;
}
}
#endregion
#region SatelliteNr
public int SatelliteNr
{
get { return this.GetWord(offSatelliteNr); }
set { this.SetWord(offSatelliteNr, value); }
}
#endregion
#region ProgramNr
public override ushort ProgramNr
{
get { return base.ProgramNr; }
set
{
base.ProgramNr = value;
this.IsProgNrCustomized = true;
}
}
#endregion
#region ProgramNrPreset
public int ProgramNrPreset
{
get { return this.GetWord(offProgramNrPreset); }
set { this.SetWord(offProgramNrPreset, (ushort)value); }
}
#endregion
#region IsProgNrCustomized
public bool IsProgNrCustomized
{
get { return GetFlag(offProgNrCustomized, maskProgNrCustomized); }
set { SetFlag(offProgNrCustomized, maskProgNrCustomized, value); }
}
#endregion
#region Name
public override string Name
{
get
{
string longName, shortName;
this.dvbsStringDecoder.GetChannelNames(this.NamePtr, this.NameLength, out longName, out shortName);
return longName;
}
set { ChannelDataMapping.SetChannelName(this, value, this.dvbsStringDecoder.DefaultEncoding); }
}
#endregion
#region ShortName
public override string ShortName
{
get
{
string longName, shortName;
this.dvbsStringDecoder.GetChannelNames(this.NamePtr, this.NameLength, out longName, out shortName);
return shortName;
}
}
#endregion
#region Favorites
public override Favorites Favorites
{
get { return (Favorites)((GetByte(offFavorites)>>2) & 0x0F); }
set
{
var newVal = (GetByte(offFavorites) & 0xC3) | (byte)((byte)value << 2);
SetByte(offFavorites, (byte)newVal);
}
}
#endregion
#region TransponderIndex
public ushort TransponderIndex
{
get { return GetWord(offTransponderIndex); }
set { SetWord(offTransponderIndex, value); }
}
#endregion
#region Validate()
public string Validate()
{
bool ok = true;
List<string> warnings = new List<string>();
ok &= ValidateByte(offTransponderIndex) || AddWarning(warnings, "Transponder index");
ok &= ValidateWord(offProgramNr) || AddWarning(warnings, "Program#");
if (ok)
return null;
StringBuilder sb = new StringBuilder();
foreach (var warning in warnings)
{
if (sb.Length > 0)
sb.Append(", ");
sb.Append(warning);
}
return sb.ToString();
}
#endregion
#region AddWarning()
private bool AddWarning(List<string> warnings, string p)
{
warnings.Add(p);
return false;
}
#endregion
#region ValidateByte()
private bool ValidateByte(string key)
{
var offsets = this.GetOffsets(key);
if (offsets == null || offsets.Length < 1)
return true;
byte value = *(this.DataPtr + offsets[0]);
bool ok = true;
foreach (int offset in offsets)
{
if (this.DataPtr[offset] != value)
ok = false;
}
return ok;
}
#endregion
#region ValidateWord()
private bool ValidateWord(string key)
{
var offsets = this.GetOffsets(key);
if (offsets == null || offsets.Length < 1)
return true;
ushort value = *(ushort*)(this.DataPtr + offsets[0]);
bool ok = true;
foreach (int offset in offsets)
{
if (*(ushort*)(this.DataPtr + offset) != value)
ok = false;
}
return ok;
}
#endregion
}
}

View File

@@ -0,0 +1,65 @@
namespace ChanSort.Loader.TllFile
{
public class DvbsDataLayout
{
public readonly int satCount;
public readonly int satLength;
public readonly int sizeOfTransponderBlockHeader;
public readonly int transponderCount;
public readonly int transponderLength;
public readonly int sizeOfChannelLinkedListEntry = 8;
public readonly int dvbsMaxChannelCount;
public readonly int dvbsChannelLength;
public readonly int lnbCount;
public readonly int lnbLength;
public readonly int[] dvbsSubblockLength;
public int LnbBlockHeaderSize = 12;
public DvbsDataLayout(Api.IniFile.Section iniSection)
{
this.satCount = iniSection.GetInt("satCount");
this.satLength = iniSection.GetInt("satLength");
this.transponderCount = iniSection.GetInt("transponderCount");
this.transponderLength = iniSection.GetInt("transponderLength");
this.sizeOfTransponderBlockHeader = 14 + transponderCount/8 + transponderCount*6 + 2;
this.dvbsMaxChannelCount = iniSection.GetInt("dvbsChannelCount");
this.dvbsChannelLength = iniSection.GetInt("dvbsChannelLength");
this.lnbCount = iniSection.GetInt("lnbCount");
this.lnbLength = iniSection.GetInt("lnbLength");
this.dvbsSubblockLength = new[]
{
12, // header
14 + 2 + this.satCount + this.satCount*this.satLength, // satellites
sizeOfTransponderBlockHeader - 4 + transponderCount * transponderLength, // transponder
12 + dvbsMaxChannelCount/8 + dvbsMaxChannelCount*sizeOfChannelLinkedListEntry + dvbsMaxChannelCount * dvbsChannelLength, // channels
LnbBlockHeaderSize - 4 + lnbCount * lnbLength // sat/LNB-Config
};
}
/// <summary>
/// relative to start of DVBS-Block (including the intial 4 length bytes)
/// </summary>
public int ChannelListHeaderOffset
{
get { return 4 + this.dvbsSubblockLength[0] + this.dvbsSubblockLength[1] + this.dvbsSubblockLength[2]; }
}
/// <summary>
/// relative to start of DVBS-Block (including the intial 4 length bytes)
/// </summary>
public int SequenceTableOffset
{
get { return ChannelListHeaderOffset + 12 + dvbsMaxChannelCount/8; }
}
/// <summary>
/// relative to start of DVBS-Block (including the intial 4 length bytes)
/// </summary>
public int ChannelListOffset
{
get { return SequenceTableOffset + dvbsMaxChannelCount*sizeOfChannelLinkedListEntry; }
}
}
}

View File

@@ -1,8 +1,8 @@
using ChanSort.Api;
namespace ChanSort.Plugin.TllFile
namespace ChanSort.Loader.TllFile
{
public class FirmwareDataMapping : DataMapping
public class FirmwareData : DataMapping
{
private const string offSize = "offSize";
private const string offSystemLock = "offSystemLock";
@@ -10,20 +10,16 @@ namespace ChanSort.Plugin.TllFile
private const string offHbbTvEnabled = "offHbbTvEnabled";
private const string offHotelModeEnabled = "offHotelModeEnabled";
private const string offHotelModeDtvUpdate = "offHotelModeDtvUpdate";
private const string offHotelMenuAccessCode = "offHotelMenuAccessCode";
private const string offHotelMenuPin = "offHotelMenuPin";
private const string offSettingsChannelUpdate = "offSettingsChannelUpdate";
public FirmwareDataMapping(IniFile.Section settings, int structureLength) :
base(settings, structureLength, null)
public FirmwareData(IniFile.Section settings) :
base(settings)
{
}
public uint Size { get { return this.GetDword(offSize); } }
public long Size { get { return this.GetDword(offSize); } }
public bool SystemLocked { get { return this.GetByte(offSystemLock) != 0; } }
public string TvPassword { get { return CodeToString(this.GetDword(offTvPassword)); } }
public string HotelMenuAccessCode { get { return CodeToString(this.GetDword(offHotelMenuAccessCode)); } }
public string HotelMenuPin { get { return CodeToString(this.GetDword(offHotelMenuPin)); } }
public string TvPassword { get { return CodeToString((uint)this.GetDword(offTvPassword)); } }
public bool SettingsAutomaticChannelUpdate

View File

@@ -1,49 +0,0 @@
namespace ChanSort.Plugin.TllFile
{
public class ModelConstants
{
public readonly string series;
public readonly byte[] magicBytes;
public int actChannelLength; // auto-detect
public readonly int satCount;
public readonly int satLength;
public readonly int sizeOfTransponderBlockHeader;
public readonly int transponderCount;
public readonly int transponderLength;
public readonly int sizeOfZappingTableEntry = 8;
public readonly int dvbsMaxChannelCount;
public readonly int dvbsChannelLength;
public readonly int lnbCount;
public readonly int lnbLength;
public readonly int[] dvbsSubblockLength;
public bool hasDvbSBlock;
public int firmwareBlockLength; // auto-detect
public ModelConstants(Api.IniFile.Section iniSection)
{
this.series = iniSection.Name;
this.magicBytes = iniSection.GetBytes("magicBytes");
this.satCount = iniSection.GetInt("satCount");
this.satLength = iniSection.GetInt("satLength");
this.transponderCount = iniSection.GetInt("transponderCount");
this.transponderLength = iniSection.GetInt("transponderLength");
this.sizeOfTransponderBlockHeader = 14 + transponderCount/8 + transponderCount*6 + 2;
this.dvbsMaxChannelCount = iniSection.GetInt("dvbsChannelCount");
this.dvbsChannelLength = iniSection.GetInt("dvbsChannelLength");
this.lnbCount = iniSection.GetInt("lnbCount");
this.lnbLength = iniSection.GetInt("lnbLength");
this.dvbsSubblockLength = new[]
{
12,
14 + 2 + this.satCount + this.satCount*this.satLength, // 2896
sizeOfTransponderBlockHeader - 4 + transponderCount * transponderLength, // 110712
12 + dvbsMaxChannelCount/8 + dvbsMaxChannelCount*sizeOfZappingTableEntry + dvbsMaxChannelCount * dvbsChannelLength, // 602552
8 + lnbCount * lnbLength // 1768
};
}
}
}

View File

@@ -2,16 +2,16 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("Test.Plugin.TllFile")]
[assembly: InternalsVisibleTo("Test.Loader.TllFile")]
// 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.Plugin.TllFile")]
[assembly: AssemblyTitle("ChanSort.Loader.TllFile")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ChanSort.Plugin.TllFile")]
[assembly: AssemblyProduct("ChanSort.Loader.TllFile")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace ChanSort.Plugin.TllFile {
namespace ChanSort.Loader.TllFile {
using System;
@@ -39,7 +39,7 @@ namespace ChanSort.Plugin.TllFile {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChanSort.Plugin.TllFile.Resource", typeof(Resource).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChanSort.Loader.TllFile.Resource", typeof(Resource).Assembly);
resourceMan = temp;
}
return resourceMan;
@@ -60,15 +60,6 @@ namespace ChanSort.Plugin.TllFile {
}
}
/// <summary>
/// Looks up a localized string similar to File format is not supported: bad header.
/// </summary>
internal static string TllFileSerializer_ERR_badFileHeader {
get {
return ResourceManager.GetString("TllFileSerializer_ERR_badFileHeader", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Channel #{0} (Pr# {1}) was erased because it is a duplicate of channel #{2} (Pr# {3}): {4}.
/// </summary>

View File

@@ -117,9 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TllFileSerializer_ERR_badFileHeader" xml:space="preserve">
<value>Ungültiges Dateiformat: Dateikopf unbekannt</value>
</data>
<data name="TllFileSerializer_ERR_wrongChecksum" xml:space="preserve">
<value>Prüfsummenfehler: berechnet wurde {1:x8} aber Datei enthält {0:x8}</value>
</data>

View File

@@ -98,9 +98,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TllFileSerializer_ERR_badFileHeader" xml:space="preserve">
<value>File format is not supported: bad header</value>
</data>
<data name="TllFileSerializer_ERR_wrongChecksum" xml:space="preserve">
<value>Wrong checksum: calculated {1:x8} but file has {0:x8}</value>
</data>

View File

@@ -0,0 +1,44 @@
using ChanSort.Api;
namespace ChanSort.Loader.TllFile
{
class SatChannel : TllChannelBase
{
private const string _SatConfigIndex = "offSatelliteNr";
private const string _TransponderIndex = "offTransponderIndex";
public bool InUse { get; private set; }
public SatChannel(int order, int slot, DataMapping data, DataRoot dataRoot) : base(data)
{
this.InUse = data.GetWord(_SatConfigIndex) != 0xFFFF;
if (!InUse)
return;
this.InitCommonData(slot, SignalSource.DvbS, data);
this.InitDvbData(data);
int transponderIndex = data.GetWord(_TransponderIndex);
Transponder transponder = dataRoot.Transponder.TryGet(transponderIndex);
Satellite sat = transponder.Satellite;
this.Satellite = sat.Name;
this.SatPosition = sat.OrbitalPosition;
this.RecordOrder = order;
this.TransportStreamId = transponder.TransportStreamId;
this.OriginalNetworkId = transponder.OriginalNetworkId;
this.SymbolRate = transponder.SymbolRate;
this.Polarity = transponder.Polarity;
this.FreqInMhz = transponder.FrequencyInMhz;
}
public override void UpdateRawData()
{
base.UpdateRawData();
// bool deleted = this.NewProgramNr == 0;
// if (deleted)
// mapping.SetWord(_SatConfigIndex, 0xFFFF);
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace ChanSort.Loader.TllFile
{
internal class SatChannelListHeader
{
private readonly byte[] data;
private readonly int baseOffset;
public SatChannelListHeader(byte[] data, int offset) { this.data = data; this.baseOffset = offset; }
public uint Checksum { get { return BitConverter.ToUInt32(data, baseOffset + 0); } }
public int LinkedListStartIndex { get { return BitConverter.ToInt16(data, baseOffset + 8); }}
public int LinkedListEndIndex1 { get { return BitConverter.ToInt16(data, baseOffset + 10); } }
public int LinkedListEndIndex2 { get { return BitConverter.ToInt16(data, baseOffset + 12); } }
public int ChannelCount { get { return BitConverter.ToInt16(data, baseOffset + 14); } }
public int Size { get { return 16; } }
}
}

View File

@@ -0,0 +1,31 @@
using System;
namespace ChanSort.Loader.TllFile
{
internal class SatTransponder
{
private readonly byte[] data;
public int BaseOffset { get; set; }
public SatTransponder(byte[] data)
{
this.data = data;
}
public int Frequency { get { return BitConverter.ToInt16(data, BaseOffset + 12); } }
public int OriginalNetworkId { get { return BitConverter.ToInt16(data, BaseOffset + 18); } }
public int TransportStreamId { get { return BitConverter.ToInt16(data, BaseOffset + 20); } }
public int SymbolRate
{
get { return BitConverter.ToInt16(data, BaseOffset + 25); }
set
{
data[BaseOffset + 25] = (byte)value;
data[BaseOffset + 26] = (byte)(value >> 8);
}
}
public int SatIndex { get { return data[BaseOffset + 36]; } }
}
}

View File

@@ -0,0 +1,132 @@
using ChanSort.Api;
namespace ChanSort.Loader.TllFile
{
public class TllChannelBase : ChannelInfo
{
// common
private const string _ProgramNr = "offProgramNr";
private const string _ProgramNr2 = "offProgramNr2"; // not for DVB-S
private const string _Name = "offName";
private const string _NameLength = "offNameLength";
private const string _Favorites = "offFavorites"; // not for DVB-S (which only uses Favorite2)
private const string _Deleted = "Deleted";
private const string _Favorites2 = "offFavorites2";
private const string _Encrypted = "Encrypted";
private const string _Lock = "Lock";
private const string _Skip = "Skip";
private const string _Hide = "Hide";
private const string _Moved = "ProgNrCustomized";
// 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";
protected readonly DataMapping mapping;
protected readonly byte[] rawData;
internal readonly int baseOffset;
protected TllChannelBase(DataMapping data)
{
this.mapping = data;
this.rawData = data.Data;
this.baseOffset = data.BaseOffset;
}
#region InitCommonData()
protected void InitCommonData(int slot, SignalSource signalSource, DataMapping data)
{
this.RecordIndex = slot;
this.SignalSource = signalSource;
var nr = data.GetWord(_ProgramNr);
this.SignalType = this.GetSignalType(nr);
this.OldProgramNr = (nr & 0x3FFF);
this.ParseNames();
this.Favorites = (Favorites)((data.GetByte(_Favorites2) & 0x3C) >> 2);
this.Lock = data.GetFlag(_Lock);
this.Skip = data.GetFlag(_Skip);
this.Hidden = data.GetFlag(_Hide);
this.Encrypted = data.GetFlag(_Encrypted);
this.IsDeleted = data.GetFlag(_Deleted);
}
#endregion
#region InitDvbData()
protected void InitDvbData(DataMapping data)
{
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);
}
#endregion
#region GetSignalType()
protected SignalType GetSignalType(uint programNr)
{
if ((programNr & 0x4000) != 0)
return SignalType.Radio;
return SignalType.Tv;
}
#endregion
#region ParseNames()
private void ParseNames()
{
mapping.SetDataPtr(this.rawData, this.baseOffset);
DvbStringDecoder dec = new DvbStringDecoder(mapping.DefaultEncoding);
string longName, shortName;
dec.GetChannelNames(this.rawData, this.baseOffset + mapping.GetOffsets(_Name)[0], mapping.GetByte(_NameLength),
out longName, out shortName);
this.Name = longName;
this.ShortName = shortName;
}
#endregion
#region UpdateRawData()
public override void UpdateRawData()
{
mapping.SetDataPtr(this.rawData, this.baseOffset);
mapping.SetWord(_ProgramNr, this.NewProgramNr + (this.SignalType == SignalType.Radio ? 0x4000 : 0));
mapping.SetWord(_ProgramNr2, (mapping.GetWord(_ProgramNr2) & 0x0003) | (this.NewProgramNr << 2));
if (this.IsNameModified)
{
mapping.SetString(_Name, this.Name, 40);
mapping.SetByte(_NameLength, this.Name.Length);
this.IsNameModified = false;
}
mapping.SetByte(_Favorites2, (mapping.GetByte(_Favorites2)) & 0xC3 | ((byte) this.Favorites << 2));
mapping.SetByte(_Favorites, (mapping.GetByte(_Favorites) & 0xF0) | (byte)this.Favorites);
mapping.SetFlag(_Skip, this.Skip);
mapping.SetFlag(_Lock, this.Lock);
mapping.SetFlag(_Hide, this.Hidden);
if (this.NewProgramNr == 0)
{
mapping.SetFlag(_Deleted, true);
mapping.SetByte("off"+_Moved, 0); //skip,lock,hide,moved
}
else
mapping.SetFlag(_Moved, true);
}
#endregion
#region ChangeEncoding()
public override void ChangeEncoding(System.Text.Encoding encoding)
{
this.mapping.DefaultEncoding = encoding;
this.ParseNames();
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,11 +5,15 @@ using System.Data.SqlClient;
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.TllFile
namespace ChanSort.Loader.TllFile
{
/// <summary>
/// For research purposes this class writes DVB-S channel information into a database
/// It is not used for production.
/// </summary>
public partial class TllFileSerializer
{
#region SQL
#region SQL (create table)
/*
@@ -53,9 +57,12 @@ from channel c inner join chanseq s on s.listid=c.listid and s.slot=c.slot
*/
#endregion
private unsafe void StoreToDatabase()
#region StoreToDatabase()
private void StoreToDatabase()
{
return;
if (this.dvbsBlockSize == 0)
return;
var list = this.DataRoot.GetChannelList(SignalSource.DvbS, SignalType.Tv, false);
if (list == null)
return;
@@ -69,45 +76,12 @@ from channel c inner join chanseq s on s.listid=c.listid and s.slot=c.slot
{
var listId = InsertListData(cmd);
fixed (byte* ptr = this.fileContent)
{
InsertSequenceData(ptr, cmd, listId);
InsertChannelData(ptr, cmd, listId);
}
InsertChannelLinkedList(cmd, listId);
InsertChannelData(cmd, listId);
}
}
}
private unsafe void InsertSequenceData(byte* ptr, DbCommand cmd, int listId)
{
cmd.Parameters.Clear();
cmd.CommandText = "insert into chanseq(listid,seq,slot) values (" + listId + ",@seq,@slot)";
var pSeq = cmd.CreateParameter();
pSeq.ParameterName = "@seq";
pSeq.DbType = DbType.Int32;
cmd.Parameters.Add(pSeq);
var pSlot = cmd.CreateParameter();
pSlot.ParameterName = "@slot";
pSlot.DbType = DbType.Int32;
cmd.Parameters.Add(pSlot);
SatChannelListHeader* header = (SatChannelListHeader*) (ptr + this.dvbsChannelHeaderOffset);
int seq = 0;
ushort tableIndex = header->LinkedListStartIndex;
while(tableIndex != 0xFFFF)
{
ushort* entry = (ushort*)(ptr + this.dvbsChannelLinkedListOffset + tableIndex*c.sizeOfZappingTableEntry);
pSeq.Value = seq;
if (entry[2] != tableIndex)
break;
pSlot.Value = (int)tableIndex;
cmd.ExecuteNonQuery();
tableIndex = entry[1];
++seq;
}
}
#endregion
#region InsertListData()
private int InsertListData(DbCommand cmd)
@@ -127,36 +101,75 @@ from channel c inner join chanseq s on s.listid=c.listid and s.slot=c.slot
}
#endregion
#region InsertChannelLinkedList()
private void InsertChannelLinkedList(DbCommand cmd, int listId)
{
cmd.Parameters.Clear();
cmd.CommandText = "insert into chanseq(listid,seq,slot) values (" + listId + ",@seq,@slot)";
var pSeq = cmd.CreateParameter();
pSeq.ParameterName = "@seq";
pSeq.DbType = DbType.Int32;
cmd.Parameters.Add(pSeq);
var pSlot = cmd.CreateParameter();
pSlot.ParameterName = "@slot";
pSlot.DbType = DbType.Int32;
cmd.Parameters.Add(pSlot);
SatChannelListHeader header = new SatChannelListHeader(this.fileContent,
this.dvbsBlockOffset + this.satConfig.ChannelListHeaderOffset);
int seq = 0;
int tableIndex = header.LinkedListStartIndex;
int linkedListOffset = this.satConfig.SequenceTableOffset;
while (tableIndex != 0xFFFF)
{
int entryOffset = linkedListOffset + tableIndex * satConfig.sizeOfChannelLinkedListEntry;
pSeq.Value = seq;
if (BitConverter.ToInt16(this.fileContent, entryOffset + 4) != tableIndex)
break;
pSlot.Value = tableIndex;
cmd.ExecuteNonQuery();
tableIndex = BitConverter.ToInt16(this.fileContent, entryOffset + 2);
++seq;
}
}
#endregion
#region InsertChannelData()
private unsafe void InsertChannelData(byte* ptr, DbCommand cmd, int listId)
private void InsertChannelData(DbCommand cmd, int listId)
{
PrepareChannelInsert(cmd);
dvbsMapping.DataPtr = ptr + this.dvbsChannelListOffset;
DvbStringDecoder decoder = new DvbStringDecoder(this.DefaultEncoding);
DataMapping dvbsMapping = this.dvbsMappings.GetMapping(this.dvbsBlockSize);
dvbsMapping.SetDataPtr(this.fileContent, this.dvbsBlockOffset + this.satConfig.ChannelListOffset);
for (int slot = 0; slot < this.dvbsChannelCount; slot++)
{
cmd.Parameters["@listid"].Value = listId;
cmd.Parameters["@slot"].Value = slot;
cmd.Parameters["@seq"].Value = DBNull.Value;
cmd.Parameters["@isdel"].Value = dvbsMapping.InUse ? 0 : 1;
cmd.Parameters["@progmask"].Value = dvbsMapping.ProgramNr;
cmd.Parameters["@prognr"].Value = (dvbsMapping.ProgramNr & 0x3FFF);
cmd.Parameters["@progfix"].Value = dvbsMapping.ProgramNrPreset;
cmd.Parameters["@name"].Value = dvbsMapping.Name;
cmd.Parameters["@tpnr"].Value = dvbsMapping.TransponderIndex;
var transp = this.DataRoot.Transponder.TryGet(dvbsMapping.TransponderIndex);
cmd.Parameters["@isdel"].Value = dvbsMapping.GetFlag("InUse") ? 0 : 1;
cmd.Parameters["@progmask"].Value = dvbsMapping.GetWord("offProgramNr");
cmd.Parameters["@prognr"].Value = dvbsMapping.GetWord("offProgramNr") & 0x3FFF;
cmd.Parameters["@progfix"].Value = dvbsMapping.GetWord("offProgramNrPreset");
int absNameOffset = dvbsMapping.BaseOffset + dvbsMapping.GetOffsets("offName")[0];
string longName, shortName;
decoder.GetChannelNames(fileContent, absNameOffset, dvbsMapping.GetByte("offNameLength"), out longName, out shortName);
cmd.Parameters["@name"].Value = longName;
cmd.Parameters["@tpnr"].Value = dvbsMapping.GetWord("offTransponderIndex");
var transp = this.DataRoot.Transponder.TryGet(dvbsMapping.GetWord("offTransponderIndex"));
cmd.Parameters["@satnr"].Value = transp == null ? (object)DBNull.Value : transp.Satellite.Id;
cmd.Parameters["@onid"].Value = transp == null ? (object)DBNull.Value : transp.OriginalNetworkId;
cmd.Parameters["@tsid"].Value = transp == null ? (object)DBNull.Value : transp.TransportStreamId;
cmd.Parameters["@ssid"].Value = (int)dvbsMapping.ServiceId;
cmd.Parameters["@ssid"].Value = (int)dvbsMapping.GetWord("offServiceId");
cmd.Parameters["@uid"].Value = transp == null
? (object) DBNull.Value
: transp.TransportStreamId + "-" + transp.OriginalNetworkId + "-" +
dvbsMapping.ServiceId;
dvbsMapping.GetWord("offServiceId");
cmd.Parameters["@favcrypt"].Value = (int)dvbsMapping.GetByte("offFavorites");
cmd.Parameters["@lockskiphide"].Value = (int)dvbsMapping.GetByte("offLock");
cmd.ExecuteNonQuery();
dvbsMapping.Next();
dvbsMapping.BaseOffset += this.satConfig.dvbsChannelLength;
}
}
#endregion

View File

@@ -1,185 +1,27 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.IO;
using ChanSort.Api;
namespace ChanSort.Plugin.TllFile
namespace ChanSort.Loader.TllFile
{
public class TllFileSerializerPlugin : ISerializerPlugin
{
private const int MAX_FILE_SIZE = 16*1000*1000;
private readonly string ERR_modelUnknown = Resource.TllFileSerializerPlugin_ERR_modelUnknown;
private readonly string ERR_fileTooBig = Resource.TllFileSerializerPlugin_ERR_fileTooBig;
private static readonly byte[] DVBS_S2 = Encoding.ASCII.GetBytes("DVBS-S2");
private readonly MappingPool<ActChannelDataMapping> actMappings = new MappingPool<ActChannelDataMapping>("Analog and DVB-C/T");
private readonly MappingPool<DvbsChannelDataMapping> dvbsMappings = new MappingPool<DvbsChannelDataMapping>("DVB-S");
private readonly MappingPool<FirmwareDataMapping> firmwareMappings = new MappingPool<FirmwareDataMapping>("Firmware");
private readonly List<ModelConstants> modelConstants = new List<ModelConstants>();
private string series = "";
public string PluginName { get { return Resource.TllFileSerializerPlugin_PluginName; } }
public string FileFilter { get { return "*.TLL"; } }
public TllFileSerializerPlugin()
{
this.ReadConfigurationFromIniFile();
}
#region ReadConfigurationFromIniFile()
private void ReadConfigurationFromIniFile()
{
DvbStringDecoder dvbsStringDecoder = new DvbStringDecoder(null);
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 recordLength = idx < 0 ? 0 : int.Parse(section.Name.Substring(idx + 1));
if (section.Name.StartsWith("FileConfiguration"))
this.ReadModelConstants(section);
else if (section.Name.StartsWith("ACTChannelDataMapping"))
actMappings.AddMapping(new ActChannelDataMapping(section, recordLength, dvbsStringDecoder));
else if (section.Name.StartsWith("SatChannelDataMapping"))
dvbsMappings.AddMapping(new DvbsChannelDataMapping(section, recordLength, dvbsStringDecoder));
else if (section.Name.StartsWith("FirmwareData"))
firmwareMappings.AddMapping(new FirmwareDataMapping(section, recordLength));
}
}
private void ReadModelConstants(IniFile.Section section)
{
if (this.series.Length > 0)
this.series += ",";
this.series += section.Name;
ModelConstants c = new ModelConstants(section);
this.modelConstants.Add(c);
}
#endregion
#region CreateSerializer()
public SerializerBase CreateSerializer(string inputFile)
{
long fileSize = new FileInfo(inputFile).Length;
if (fileSize > MAX_FILE_SIZE)
throw new IOException(string.Format(ERR_fileTooBig, fileSize, MAX_FILE_SIZE));
byte[] fileContent = File.ReadAllBytes(inputFile);
ModelConstants model = this.DetermineModel(fileContent);
if (model == null)
throw new IOException(ERR_modelUnknown);
return new TllFileSerializer(inputFile, model,
this.actMappings.GetMapping(model.actChannelLength),
this.dvbsMappings.GetMapping(model.dvbsChannelLength),
this.firmwareMappings.GetMapping(model.firmwareBlockLength, false),
fileContent);
return new TllFileSerializer(inputFile);
}
#endregion
#region DetermineModel()
private ModelConstants DetermineModel(byte[] fileContent)
{
foreach (var model in this.modelConstants)
{
if (this.IsModel(fileContent, model))
return model;
}
return null;
}
#endregion
#region IsModel()
private unsafe bool IsModel(byte[] fileContent, ModelConstants c)
{
c.hasDvbSBlock = false;
fixed (byte* p = fileContent)
{
long fileSize = fileContent.Length;
// check magic file header
uint offset = 0;
if (fileSize < c.magicBytes.Length)
return false;
if (!ByteCompare(p, c.magicBytes))
return false;
offset += (uint)c.magicBytes.Length;
// analog channel block
if (offset + 8 > fileSize) return false;
uint blockSize = *(uint*)(p + offset);
uint channelCount = *(uint*) (p + offset + 4);
if (blockSize < 4 + channelCount)
return false;
if (blockSize > 4 && channelCount > 0)
c.actChannelLength = (int)((blockSize - 4)/channelCount);
offset += 4 + blockSize;
// firmware data block
if (offset + 4 > fileSize) return false;
blockSize = *(uint*) (p + offset);
c.firmwareBlockLength = (int)blockSize;
offset += 4 + blockSize;
// DVB-C/T channel block
if (offset + 8 > fileSize) return false;
blockSize = *(uint*) (p + offset);
channelCount = *(uint*) (p + offset + 4);
if (blockSize < 4 + channelCount)
return false;
if (blockSize > 4 && channelCount > 0)
c.actChannelLength = (int)((blockSize - 4) / channelCount);
offset += 4 + blockSize;
// optional blocks
while (offset != fileSize)
{
if (offset + 4 > fileSize)
return false;
blockSize = *(uint*) (p + offset);
// check for DVBS-S2 block
if (blockSize >= sizeof(DvbSBlockHeader))
{
DvbSBlockHeader* header = (DvbSBlockHeader*) (p + offset);
if (ByteCompare(header->DvbS_S2, DVBS_S2))
{
c.hasDvbSBlock = true;
int length = sizeof(DvbSBlockHeader) +
c.satCount*c.satLength +
c.sizeOfTransponderBlockHeader +
c.transponderCount*c.transponderLength +
sizeof(SatChannelListHeader) +
c.dvbsMaxChannelCount/8 +
c.dvbsMaxChannelCount*c.sizeOfZappingTableEntry +
c.dvbsMaxChannelCount*c.dvbsChannelLength +
sizeof(LnbBlockHeader) + c.lnbCount*c.lnbLength;
if (length != 4 + blockSize)
return false;
}
}
offset += 4 + blockSize;
}
return true;
}
}
#endregion
#region ByteCompare()
private static unsafe bool ByteCompare(byte* buffer, byte[] expected)
{
for (int i = 0; i < expected.Length; i++)
{
if (buffer[i] != expected[i])
return false;
}
return true;
}
#endregion
}
}

View File

@@ -1,169 +0,0 @@
using System.Runtime.InteropServices;
namespace ChanSort.Plugin.TllFile
{
/*
TllFileHeader? ("ZZZZ" or nothing)
ChannelBlock
AnalogChannel[]
FirmwareBlock
ChannelBlock
DvbCtChannel[]
DvbSBlockHeader
TllSatellite[64]
TransponderBlockHeader
TllTransponder[2400]
SatChannelListHeader
DvbSChannel[7520]
LnbBlockHeader
Lnb[40]
SettingsBlock?
*/
#region struct ChannelBlock
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ChannelBlock
{
public uint BlockSize; // = 4 + ChannelCount * ChannelLength
public uint ChannelCount;
public uint ChannelLength { get { return ChannelCount == 0 ? 0 : (BlockSize - 4) / ChannelCount; } }
public byte StartOfChannelList;
}
#endregion
#region struct FirmwareBlock
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct FirmwareBlock
{
public uint BlockSize;
public fixed byte Unknown_0x0000[35631];
public fixed byte HotelMenu[29];
public fixed byte Unknown_0x8B4C[1204]; // or more
}
#endregion
#region struct DvbSBlockHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct DvbSBlockHeader
{
public uint BlockSize;
public uint Crc32ForSubblock1;
public fixed byte DvbS_S2 [8]; // "DVBS-S2\0"
public ushort Unknown_0x10; // 0x0007
public ushort Unknown_0x12; // 0x0004 // 0x0000
public uint Crc32ForSubblock2;
public const int Unknown0x18_Length = 12;
public fixed byte Unknown_0x18[Unknown0x18_Length];
public ushort SatOrderLength;
public fixed byte SatOrder[64];
public fixed byte Unknown [2];
//public fixed TllSatellite Satellites[64]
}
#endregion
#region struct TllSatellite
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct TllSatellite
{
public const int SatNameLength =32;
public fixed byte Name [SatNameLength];
public byte PosDeg;
public byte PosCDeg;
public byte Unknown_34; // typically 0
public byte Unknown_35; // typically 2
public ushort Unknown_36; // 0xFFFF if sat is not used
public ushort Unknown_38; // 0xFFFF if sat is not used
public ushort TransponderCount;
public ushort Unknown_42; // typically 0
}
#endregion
#region struct TransponderLinkedList
public struct TransponderLinkedList
{
public ushort Prev;
public ushort Next;
public ushort Current;
}
#endregion
#region struct TransponderBlockHeader
public unsafe struct TransponderBlockHeader
{
public uint Crc32;
public ushort Unknown1;
public ushort HeadIndex;
public ushort TailIndex1;
public ushort TailIndex2;
public ushort TransponderCount;
public fixed byte AllocationBitmap [2400/8];
public fixed ushort TransponderLinkedList [2400*3];
public ushort Unknown3;
// public fixed TllTransponder Transponders[2400]
}
#endregion
#region struct TllTransponder
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct TllTransponder
{
public fixed byte Unknown_0x00 [10];
public ushort Index;
public ushort Frequency;
public fixed byte Unknown_0x0E [4];
public ushort NetworkId;
public ushort TransportStreamId;
public fixed byte Unknown_0x16 [3];
public ushort SymbolRateAndPolarity;
public fixed byte Unknown_0x1B [9];
public byte SatIndex;
public fixed byte Unknown_0x25 [3];
//public int SymbolRate { get { return this.SymbolRateAndPolarity & 0x7FFFF; } }
public ushort SymbolRate { get { return this.SymbolRateAndPolarity; } set { this.SymbolRateAndPolarity = value; } }
public char Polarity { get { return '\0'; } }
}
#endregion
#region struct SatChannelListHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct SatChannelListHeader
{
public uint Checksum;
public fixed byte Unknown_0x04[4];
public ushort LinkedListStartIndex;
public ushort LinkedListEndIndex1;
public ushort LinkedListEndIndex2;
public ushort ChannelCount;
}
#endregion
#region struct LnbBlockHeader
public unsafe struct LnbBlockHeader
{
public uint crc32;
public ushort lastUsedIndex;
public fixed byte lnbAllocationBitmap[6];
// public Lnb lnbs[40];
}
#endregion
#region struct Lnb
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct Lnb
{
public byte SettingsID;
public fixed byte Unknown_0x0D[3];
public byte SatelliteID;
public fixed byte Unknown_0x11[3];
public fixed byte FrequencyName[12];
public ushort LOF1;
public fixed byte Unknown_0x22 [2];
public ushort LOF2;
public fixed byte Unknown_0x26 [18];
}
#endregion
}

View File

@@ -1,4 +1,4 @@
namespace ChanSort.Plugin.TllFile
namespace ChanSort.Loader.TllFile
{
partial class TvSettingsForm
{

View File

@@ -2,7 +2,7 @@
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
namespace ChanSort.Plugin.TllFile
namespace ChanSort.Loader.TllFile
{
public partial class TvSettingsForm : XtraForm
{
@@ -14,52 +14,44 @@ namespace ChanSort.Plugin.TllFile
InitializeComponent();
}
private unsafe void TvSettingsForm_Load(object sender, EventArgs e)
private void TvSettingsForm_Load(object sender, EventArgs e)
{
var items = tvSerializer.SupportedTvCountryCodes;
foreach(var item in items)
this.comboBoxEdit1.Properties.Items.Add(item);
this.comboBoxEdit1.Text = this.tvSerializer.TvCountryCode;
byte[] fileContent = this.tvSerializer.FileContent;
fixed (byte* ptr = fileContent)
var mapping = this.tvSerializer.GetFirmwareMapping();
if (mapping != null)
{
var mapping = this.tvSerializer.GetFirmwareMapping(ptr);
if (mapping != null)
{
this.cbAutoChannelUpdate.Checked = mapping.SettingsAutomaticChannelUpdate;
this.cbHbbTv.Checked = mapping.HbbTvEnabled;
this.cbHotelMode.Checked = mapping.HotelModeEnabled;
this.cbDtvUpdate.Checked = mapping.HotelModeDtvUpdate;
this.cbAutoChannelUpdate.Checked = mapping.SettingsAutomaticChannelUpdate;
this.cbHbbTv.Checked = mapping.HbbTvEnabled;
this.cbHotelMode.Checked = mapping.HotelModeEnabled;
this.cbDtvUpdate.Checked = mapping.HotelModeDtvUpdate;
this.grpFirmwareNote.Visible = false;
this.Height -= this.grpFirmwareNote.Height;
}
else
{
this.cbAutoChannelUpdate.Enabled = false;
this.cbHbbTv.Enabled = false;
this.cbHotelMode.Enabled = false;
this.cbDtvUpdate.Enabled = false;
}
this.grpFirmwareNote.Visible = false;
this.Height -= this.grpFirmwareNote.Height;
}
else
{
this.cbAutoChannelUpdate.Enabled = false;
this.cbHbbTv.Enabled = false;
this.cbHotelMode.Enabled = false;
this.cbDtvUpdate.Enabled = false;
}
}
private unsafe void btnOk_Click(object sender, EventArgs e)
private void btnOk_Click(object sender, EventArgs e)
{
this.tvSerializer.TvCountryCode = this.comboBoxEdit1.Text;
byte[] fileContent = this.tvSerializer.FileContent;
fixed (byte* ptr = fileContent)
var mapping = this.tvSerializer.GetFirmwareMapping();
if (mapping != null)
{
var mapping = this.tvSerializer.GetFirmwareMapping(ptr);
if (mapping != null)
{
mapping.SettingsAutomaticChannelUpdate = this.cbAutoChannelUpdate.Checked;
mapping.HbbTvEnabled = this.cbHbbTv.Checked;
mapping.HotelModeEnabled = this.cbHotelMode.Checked;
mapping.HotelModeDtvUpdate = this.cbDtvUpdate.Checked;
}
mapping.SettingsAutomaticChannelUpdate = this.cbAutoChannelUpdate.Checked;
mapping.HbbTvEnabled = this.cbHbbTv.Checked;
mapping.HotelModeEnabled = this.cbHotelMode.Checked;
mapping.HotelModeDtvUpdate = this.cbDtvUpdate.Checked;
}
}