Files
ChanSort/ChanSort.Plugin.TllFile/TllFileSerializer.cs

728 lines
24 KiB
C#
Raw Normal View History

#define SYMBOL_RATE_ROUNDING
#undef STORE_DVBS_CHANNELS_IN_DATABASE
2013-03-31 14:09:38 +02:00
using System;
2013-03-31 14:09:38 +02:00
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
2013-03-31 14:09:38 +02:00
using System.Text;
using System.Windows.Forms;
using ChanSort.Api;
namespace ChanSort.Loader.TllFile
2013-03-31 14:09:38 +02:00
{
public partial class TllFileSerializer : SerializerBase
{
private const long MaxFileSize = 2000000;
private readonly string ERR_fileTooBig = Resource.TllFileSerializerPlugin_ERR_fileTooBig;
private readonly string ERR_modelUnknown = Resource.TllFileSerializerPlugin_ERR_modelUnknown;
2013-03-31 14:09:38 +02:00
private readonly string ERR_wrongChecksum = Resource.TllFileSerializer_ERR_wrongChecksum;
private readonly string ERR_dupeChannel = Resource.TllFileSerializer_ERR_dupeChannel;
private readonly MappingPool<DataMapping> actMappings = new MappingPool<DataMapping>("Analog and DVB-C/T");
private readonly MappingPool<DataMapping> dvbsMappings = new MappingPool<DataMapping>("DVB-S");
private readonly MappingPool<FirmwareData> firmwareMappings = new MappingPool<FirmwareData>("Firmware");
private readonly Dictionary<int, DvbsDataLayout> satConfigs = new Dictionary<int, DvbsDataLayout>();
private byte[] fileContent;
2013-03-31 14:09:38 +02:00
private int analogBlockOffset;
private int firmwareBlockOffset;
private int dvbctBlockOffset;
private int dvbsBlockOffset;
private int[] dvbsSubblockCrcOffset;
private int settingsBlockOffset;
private int actChannelSize;
private bool reorderPhysically;
private int analogChannelCount;
private int dvbctChannelCount;
private int dvbsChannelCount;
private DvbsDataLayout satConfig;
2013-03-31 14:09:38 +02:00
private bool isDvbsSymbolRateDiv2;
2013-03-31 14:09:38 +02:00
private Dictionary<int, int> nextChannelIndex;
private int firmwareBlockSize;
private int dvbsBlockSize;
private int settingsBlockSize;
2013-03-31 14:09:38 +02:00
private string countryCode;
private int duplicateChannels;
private int deletedChannelsHard;
private int deletedChannelsSoft;
private int dvbsChannelsAtPr0;
private bool removeDeletedActChannels = false;
2013-03-31 14:09:38 +02:00
#region ctor()
public TllFileSerializer(string inputFile) : base(inputFile)
{
this.Features.ChannelNameEdit = true;
this.Features.EraseChannelData = true;
this.Features.FileInformation = true;
this.Features.DeviceSettings = true;
2013-03-31 14:09:38 +02:00
this.SupportedTvCountryCodes = new List<string>
{
"___ (None)", "AUT (Austria)", "BEL (Belgium)", "CHE (Switzerland)",
"DEU (Germany)", "ESP (Spain)", "FRA (France)", "GBR (Great Britain)",
"GRC (Greece)", "IRL (Ireland)", "ITA (Italy)", "LUX (Luxembourg)",
"NLD (Netherlands)", "PRT (Portugal)", "SVN (Slovenia)"
2013-03-31 14:09:38 +02:00
};
this.ReadConfigurationFromIniFile();
2013-03-31 14:09:38 +02:00
}
#endregion
public IList<string> SupportedTvCountryCodes { get; private set; }
#region ReadConfigurationFromIniFile()
private void ReadConfigurationFromIniFile()
2013-03-31 14:09:38 +02:00
{
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("DvbsBlock"))
this.satConfigs.Add(recordLength, new DvbsDataLayout(section));
else if (section.Name.StartsWith("ACTChannelDataMapping"))
actMappings.AddMapping(recordLength, new DataMapping(section));
else if (section.Name.StartsWith("SatChannelDataMapping"))
dvbsMappings.AddMapping(recordLength, new DataMapping(section));
else if (section.Name.StartsWith("FirmwareData"))
firmwareMappings.AddMapping(recordLength, new FirmwareData(section));
}
2013-03-31 14:09:38 +02:00
}
#endregion
#region DisplayName
public override string DisplayName { get { return "TLL loader"; } }
#endregion
2013-03-31 14:09:38 +02:00
#region Load()
public override void Load()
2013-03-31 14:09:38 +02:00
{
long fileSize = new FileInfo(this.FileName).Length;
if (fileSize > MaxFileSize)
throw new InvalidOperationException(string.Format(ERR_fileTooBig, fileSize, MaxFileSize));
2013-03-31 14:09:38 +02:00
this.fileContent = File.ReadAllBytes(this.FileName);
int off = 0;
2013-03-31 14:09:38 +02:00
this.ReadFileHeader(ref off);
this.ReadAnalogChannelBlock(ref off);
this.ReadFirmwareDataBlock(ref off);
this.ReadDvbCtChannels(ref off);
this.ReadDvbSBlock(ref off);
this.ReadSettingsBlock(ref off);
2013-03-31 14:09:38 +02:00
#if STORE_DVBS_CHANNELS_IN_DATABASE
2013-03-31 14:09:38 +02:00
this.StoreToDatabase();
#endif
2013-03-31 14:09:38 +02:00
}
2013-03-31 14:09:38 +02:00
#endregion
#region ReadFileHeader()
private void ReadFileHeader(ref int off)
2013-03-31 14:09:38 +02:00
{
if (fileContent.Length < 4)
throw new InvalidOperationException(ERR_modelUnknown);
if (BitConverter.ToUInt32(fileContent, off) == 0x5A5A5A5A)
off += 4;
}
#endregion
2013-03-31 14:09:38 +02:00
#region ReadAnalogChannelBlock()
2013-03-31 14:09:38 +02:00
private void ReadAnalogChannelBlock(ref int off)
{
this.analogBlockOffset = off;
this.ReadActChannelBlock(ref off, out analogChannelCount, out actChannelSize,
(slot, data) => new AnalogChannel(slot, data));
2013-03-31 14:09:38 +02:00
}
#endregion
2013-03-31 14:09:38 +02:00
#region ReadFirmwareDataBlock()
private void ReadFirmwareDataBlock(ref int off)
{
this.firmwareBlockOffset = off;
this.firmwareBlockSize = this.GetBlockSize(off);
off += 4 + this.firmwareBlockSize;
}
2013-03-31 14:09:38 +02:00
#endregion
#region ReadDvbCtChannels()
private void ReadDvbCtChannels(ref int off)
{
this.dvbctBlockOffset = off;
this.ReadActChannelBlock(ref off, out dvbctChannelCount, out actChannelSize,
(slot, data) => new DtvChannel(slot, data));
}
#endregion
#region ReadDvbSBlock()
private void ReadDvbSBlock(ref int off)
2013-03-31 14:09:38 +02:00
{
int blockSize;
if (!IsDvbsBlock(off, out blockSize))
return;
this.dvbsBlockSize = blockSize;
this.dvbsBlockOffset = off;
off += 4;
this.satConfig = this.satConfigs.TryGet(blockSize);
if (satConfig != null)
this.ReadDvbsSubblocks(ref off);
else
2013-03-31 14:09:38 +02:00
{
this.DataRoot.Warnings.AppendFormat("DVB-S data format is not supported (size={0})\n", blockSize);
off += blockSize;
}
}
#endregion
2013-03-31 14:09:38 +02:00
#region ReadSettingsBlock()
private void ReadSettingsBlock(ref int off)
{
this.settingsBlockOffset = off;
if (this.settingsBlockOffset >= fileContent.Length)
{
this.settingsBlockOffset = 0;
return;
}
this.settingsBlockSize = this.GetBlockSize(off);
off += 4;
if (settingsBlockSize >= 8)
{
StringBuilder code = new StringBuilder();
for (int i = 6; i >= 4; i--)
code.Append((char)fileContent[off + i]);
this.countryCode = code.ToString();
2013-03-31 14:09:38 +02:00
}
off += settingsBlockSize;
2013-03-31 14:09:38 +02:00
}
#endregion
#region ReadActChannelBlock()
private void ReadActChannelBlock(ref int off, out int channelCount, out int recordSize,
Func<int, DataMapping, ChannelInfo> channelFactory)
2013-03-31 14:09:38 +02:00
{
recordSize = 0;
int blockSize = this.GetBlockSize(off, minSize: 2);
off += 4;
channelCount = BitConverter.ToInt32(fileContent, off);
off += 4;
if (channelCount == 0) return;
2013-03-31 14:09:38 +02:00
recordSize = GetActChannelRecordSize(off, blockSize, channelCount);
var actMapping = this.actMappings.GetMapping(recordSize);
this.reorderPhysically = actMapping.Settings.GetInt("reorderChannelData") != 0;
2013-03-31 14:09:38 +02:00
for (int i = 0; i < channelCount; i++)
{
actMapping.SetDataPtr(fileContent, off);
ChannelInfo ci = channelFactory(i, actMapping);
2013-03-31 14:09:38 +02:00
var list = this.DataRoot.GetChannelList(ci.SignalSource, ci.SignalType, true);
this.DataRoot.AddChannel(list, ci);
2013-03-31 14:09:38 +02:00
off += recordSize;
}
}
#endregion
2013-03-31 14:09:38 +02:00
#region GetBlockSize()
private int GetBlockSize(int off, int minSize = 0)
{
long len = BitConverter.ToUInt32(fileContent, off);
if (len < minSize || off + 4 + len > fileContent.Length)
throw new InvalidOperationException(ERR_modelUnknown);
return (int)len;
}
#endregion
2013-03-31 14:09:38 +02:00
#region GetActChannelRecordSize()
private int GetActChannelRecordSize(int off, int blockSize, int channelCount)
{
if ((blockSize - 4) % channelCount != 0)
throw new InvalidOperationException(ERR_modelUnknown);
int recordSize = (blockSize - 4) / channelCount;
if (off + channelCount * recordSize > fileContent.Length)
throw new InvalidOperationException(ERR_modelUnknown);
return recordSize;
2013-03-31 14:09:38 +02:00
}
#endregion
2013-03-31 14:09:38 +02:00
#region IsDvbsBlock()
private bool IsDvbsBlock(int off, out int blockSize)
{
blockSize = 0;
if (off >= fileContent.Length)
return false;
blockSize = this.GetBlockSize(off);
if (blockSize < 12)
return false;
ulong blockId = BitConverter.ToUInt64(fileContent, off + 8);
if (blockId != 0x0032532D53425644) // reverse "DVBS-S2\0"
return false;
return true;
}
2013-03-31 14:09:38 +02:00
#endregion
#region ReadDvbsSubblocks()
private void ReadDvbsSubblocks(ref int off)
2013-03-31 14:09:38 +02:00
{
this.ScanDvbSSubBlockChecksums(off);
// subblock 1 (DVBS header)
off += 16;
// subblock 2 (satellites)
off += 84; // irrelevant data
this.ReadSatellites(ref off);
// subblock 3 (transponder)
off += satConfig.sizeOfTransponderBlockHeader;
this.ReadTransponderData(ref off);
// subblock 4 (channels)
SatChannelListHeader header = new SatChannelListHeader(fileContent, off);
this.dvbsChannelCount = header.ChannelCount;
off += header.Size;
off += satConfig.dvbsMaxChannelCount/8; // skip allocation bitmap
this.ReadDvbsChannelLinkedList(ref off);
this.ReadDvbSChannels(ref off, header.LinkedListStartIndex);
// subblock 5 (satellite/LNB config)
off += satConfig.LnbBlockHeaderSize + satConfig.lnbCount*satConfig.lnbLength;
}
#endregion
#region ScanDvbSSubBlockChecksums()
private void ScanDvbSSubBlockChecksums(int off)
{
this.dvbsSubblockCrcOffset = new int[satConfig.dvbsSubblockLength.Length];
2013-03-31 14:09:38 +02:00
for (int i = 0; i < dvbsSubblockCrcOffset.Length; i++)
{
this.dvbsSubblockCrcOffset[i] = off;
int subblockLength = satConfig.dvbsSubblockLength[i];
uint fileCrc = BitConverter.ToUInt32(fileContent, off);
uint calcCrc = Crc32.CalcCrc32(fileContent, off + 4, subblockLength);
2013-03-31 14:09:38 +02:00
if (fileCrc != calcCrc)
throw new IOException(string.Format(ERR_wrongChecksum, calcCrc, fileCrc));
off += 4 + subblockLength;
2013-03-31 14:09:38 +02:00
}
}
#endregion
#region ReadSatellites()
private void ReadSatellites(ref int off)
2013-03-31 14:09:38 +02:00
{
for (int i = 0; i < satConfig.satCount; i++)
2013-03-31 14:09:38 +02:00
{
Satellite sat = new Satellite(i);
string satName = Encoding.ASCII.GetString(fileContent, off + 0, 32).TrimEnd('\0');
sat.Name = satName;
sat.OrbitalPosition = GetSatLocation(fileContent[off + 32], fileContent[off + 33]);
2013-03-31 14:09:38 +02:00
this.DataRoot.AddSatellite(sat);
off += satConfig.satLength;
2013-03-31 14:09:38 +02:00
}
}
#endregion
#region ReadTransponderData()
private void ReadTransponderData(ref int off)
2013-03-31 14:09:38 +02:00
{
var data = new SatTransponder(fileContent);
data.BaseOffset = off;
for (int i=0; i<satConfig.transponderCount; i++)
2013-03-31 14:09:38 +02:00
{
if (data.SatIndex == 0xFF)
2013-03-31 14:09:38 +02:00
continue;
#if SYMBOL_RATE_ROUNDING
ushort sr = (ushort)(data.SymbolRate & 0x7FFF);
2013-03-31 14:09:38 +02:00
if (sr % 100 >= 95)
data.SymbolRate = (ushort)((data.SymbolRate & 0x8000) | ((sr / 100 + 1) * 100));
2013-03-31 14:09:38 +02:00
#endif
Transponder transponder = new Transponder(i);
transponder.FrequencyInMhz = data.Frequency;
transponder.OriginalNetworkId = data.OriginalNetworkId;
transponder.TransportStreamId = data.TransportStreamId;
transponder.SymbolRate = data.SymbolRate & 0x7FFF;
if (data.SymbolRate == 11000)
2013-03-31 14:09:38 +02:00
this.isDvbsSymbolRateDiv2 = true;
var sat = this.DataRoot.Satellites.TryGet(data.SatIndex/2);
2013-03-31 14:09:38 +02:00
this.DataRoot.AddTransponder(sat, transponder);
data.BaseOffset += satConfig.transponderLength;
2013-03-31 14:09:38 +02:00
}
if (this.isDvbsSymbolRateDiv2)
{
foreach (var transponder in this.DataRoot.Transponder.Values)
transponder.SymbolRate *= 2;
}
off += this.satConfig.transponderCount * this.satConfig.transponderLength;
2013-03-31 14:09:38 +02:00
}
#endregion
#region ReadDvbsChannelLinkedList()
private void ReadDvbsChannelLinkedList(ref int off)
2013-03-31 14:09:38 +02:00
{
this.nextChannelIndex = new Dictionary<int, int>();
for (int i = 0; i < satConfig.dvbsMaxChannelCount; i++)
2013-03-31 14:09:38 +02:00
{
int offEntry = off + i*satConfig.sizeOfChannelLinkedListEntry;
int cur = BitConverter.ToUInt16(fileContent, offEntry + 4);
if (cur != i)
2013-03-31 14:09:38 +02:00
break;
this.nextChannelIndex.Add(cur, BitConverter.ToUInt16(fileContent, offEntry + 2));
2013-03-31 14:09:38 +02:00
}
off += satConfig.dvbsMaxChannelCount*satConfig.sizeOfChannelLinkedListEntry;
2013-03-31 14:09:38 +02:00
}
#endregion
#region ReadDvbSChannels()
private void ReadDvbSChannels(ref int off, int startIndex)
2013-03-31 14:09:38 +02:00
{
var mapping = this.dvbsMappings.GetMapping(satConfig.dvbsChannelLength);
2013-03-31 14:09:38 +02:00
int index = startIndex;
for (int i = 0; i < this.dvbsChannelCount; i++)
{
int recordOffset = off + index*satConfig.dvbsChannelLength;
mapping.SetDataPtr(fileContent, recordOffset);
SatChannel ci = new SatChannel(i, index, mapping, this.DataRoot);
if (!ci.InUse)
++this.deletedChannelsHard;
else if (ci.IsDeleted)
++this.deletedChannelsSoft;
else
2013-03-31 14:09:38 +02:00
{
var list = this.DataRoot.GetChannelList(ci.SignalSource, ci.SignalType, true);
var dupes = list.GetChannelByUid(ci.Uid);
if (dupes.Count == 0)
{
if (ci.OldProgramNr == 0)
++this.dvbsChannelsAtPr0;
this.DataRoot.AddChannel(list, ci);
}
2013-03-31 14:09:38 +02:00
else
{
// duplicate channels (ONID,TSID,SSID) cause the TV to randomly reorder channels and show wrong ones in the
// program list, so we erase all dupes here
this.DataRoot.Warnings.AppendFormat(ERR_dupeChannel, ci.RecordIndex, ci.OldProgramNr, dupes[0].RecordIndex,
dupes[0].OldProgramNr, dupes[0].Name).AppendLine();
this.EraseDuplicateDvbsChannel(recordOffset, satConfig);
++this.duplicateChannels;
}
2013-03-31 14:09:38 +02:00
}
if (!this.nextChannelIndex.TryGetValue(index, out index) || index == -1)
break;
}
off += satConfig.dvbsMaxChannelCount * satConfig.dvbsChannelLength;
2013-03-31 14:09:38 +02:00
}
#endregion
#region EraseDuplicateDvbsChannel()
private void EraseDuplicateDvbsChannel(int off, DvbsDataLayout c)
2013-03-31 14:09:38 +02:00
{
for (int i = 0; i < c.dvbsChannelLength; i++)
fileContent[off++] = 0xFF;
2013-03-31 14:09:38 +02:00
}
#endregion
#region GetSatLocation()
private string GetSatLocation(byte degree, byte fractionAndOrientation)
2013-03-31 14:09:38 +02:00
{
return string.Format("{0}.{1}{2}", degree, fractionAndOrientation & 0x0f, fractionAndOrientation < 16 ? "W" : "E");
2013-03-31 14:09:38 +02:00
}
#endregion
2013-03-31 14:09:38 +02:00
#region Save()
public override void Save(string tvOutputFile, string csvOutputFile)
2013-03-31 14:09:38 +02:00
{
int newAnalogChannelCount;
int newDvbctChannelCount;
this.UpdateRawChannelData(out newAnalogChannelCount, out newDvbctChannelCount);
2013-03-31 14:09:38 +02:00
if (!removeDeletedActChannels)
2013-03-31 14:09:38 +02:00
{
newAnalogChannelCount = this.analogChannelCount;
newDvbctChannelCount = this.dvbctChannelCount;
2013-03-31 14:09:38 +02:00
}
if (this.reorderPhysically || this.removeDeletedActChannels)
this.ReorderActChannelsPhysically();
2013-03-31 14:09:38 +02:00
if (satConfig != null)
this.UpdateDvbsChecksums();
2013-03-31 14:09:38 +02:00
using (var file = new BinaryWriter(new FileStream(tvOutputFile, FileMode.Create, FileAccess.Write)))
{
// header
file.Write(this.fileContent, 0, this.analogBlockOffset);
2013-03-31 14:09:38 +02:00
// analog
file.Write(newAnalogChannelCount*this.actChannelSize + 4);
file.Write(newAnalogChannelCount);
file.Write(fileContent, this.analogBlockOffset + 8, newAnalogChannelCount*this.actChannelSize);
2013-03-31 14:09:38 +02:00
// firmware
file.Write(fileContent, this.firmwareBlockOffset, this.firmwareBlockSize + 4);
2013-03-31 14:09:38 +02:00
// DVB-CT
file.Write(newDvbctChannelCount*this.actChannelSize + 4);
file.Write(newDvbctChannelCount);
file.Write(fileContent, this.dvbctBlockOffset + 8, newDvbctChannelCount * this.actChannelSize);
2013-03-31 14:09:38 +02:00
// DVB-S
if (this.dvbsBlockOffset != 0)
file.Write(fileContent, this.dvbsBlockOffset, this.dvbsBlockSize + 4);
2013-03-31 14:09:38 +02:00
// rest (including settings)
file.Write(fileContent, this.settingsBlockOffset, fileContent.Length - this.settingsBlockOffset);
2013-03-31 14:09:38 +02:00
}
}
#endregion
#region UpdateRawChannelData()
private void UpdateRawChannelData(out int newAnalogChannelCount, out int newDvbctChannelCount)
2013-03-31 14:09:38 +02:00
{
newAnalogChannelCount = 0;
newDvbctChannelCount = 0;
foreach (var list in this.DataRoot.ChannelLists)
2013-03-31 14:09:38 +02:00
{
foreach (TllChannelBase channel in list.Channels)
2013-03-31 14:09:38 +02:00
{
if (channel.NewProgramNr != 0)
2013-03-31 14:09:38 +02:00
{
if ((channel.SignalSource & SignalSource.Digital) == 0)
++newAnalogChannelCount;
else if (channel.SignalSource != SignalSource.DvbS)
++newDvbctChannelCount;
2013-03-31 14:09:38 +02:00
}
channel.OldProgramNr = channel.NewProgramNr;
channel.UpdateRawData();
2013-03-31 14:09:38 +02:00
}
}
}
#endregion
#region ReorderActChannelsPhysically()
private void ReorderActChannelsPhysically()
2013-03-31 14:09:38 +02:00
{
var analogTv = this.DataRoot.GetChannelList(SignalSource.AnalogCT, SignalType.Tv, false);
var analogRadio = this.DataRoot.GetChannelList(SignalSource.AnalogCT, SignalType.Radio, false);
var analog = analogTv.Channels.Union(analogRadio.Channels).ToList();
this.ReorderChannelData(this.analogBlockOffset + 8, this.actChannelSize, this.analogChannelCount, analog);
2013-03-31 14:09:38 +02:00
var dvbCtTv = this.DataRoot.GetChannelList(SignalSource.DvbCT, SignalType.Tv, false);
var dvbCtRadio = this.DataRoot.GetChannelList(SignalSource.DvbCT, SignalType.Radio, false);
var dvbCt = dvbCtTv.Channels.Union(dvbCtRadio.Channels).ToList();
this.ReorderChannelData(this.dvbctBlockOffset + 8, this.actChannelSize, this.dvbctChannelCount, dvbCt);
2013-03-31 14:09:38 +02:00
}
#endregion
#region ReorderChannelData()
private void ReorderChannelData(int channelDataOffset, int channelDataLength, int recordCount, IList<ChannelInfo> sortedList)
2013-03-31 14:09:38 +02:00
{
if (sortedList.Count == 0) return;
byte[] copy = new byte[recordCount * channelDataLength];
Array.Copy(fileContent, channelDataOffset, copy, 0, copy.Length);
int pTarget = channelDataOffset;
int slot = 0;
foreach (ChannelInfo appChannel in sortedList)
2013-03-31 14:09:38 +02:00
{
if (appChannel.NewProgramNr <= 0 && this.removeDeletedActChannels)
continue;
if (appChannel.RecordIndex != slot)
{
Array.Copy(copy, appChannel.RecordIndex*channelDataLength, fileContent, pTarget, channelDataLength);
appChannel.RecordIndex = slot;
}
++slot;
pTarget += channelDataLength;
2013-03-31 14:09:38 +02:00
}
}
#endregion
#region UpdateDvbsChecksums()
private void UpdateDvbsChecksums()
2013-03-31 14:09:38 +02:00
{
for (int i = 0; i < this.dvbsSubblockCrcOffset.Length; i++)
2013-03-31 14:09:38 +02:00
{
uint crc32 = Crc32.CalcCrc32(fileContent, this.dvbsSubblockCrcOffset[i] + 4, satConfig.dvbsSubblockLength[i]);
var bytes = BitConverter.GetBytes(crc32);
for (int j = 0; j < bytes.Length; j++)
fileContent[this.dvbsSubblockCrcOffset[i] + j] = bytes[j];
2013-03-31 14:09:38 +02:00
}
}
#endregion
#region DefaultEncoding
public override Encoding DefaultEncoding
{
get { return base.DefaultEncoding; }
set
{
if (Equals(value, this.DefaultEncoding))
return;
base.DefaultEncoding = value;
if (this.DataRoot.IsEmpty)
return;
ChangeEncoding();
}
}
#endregion
#region ChangeEncoding()
private void ChangeEncoding()
2013-03-31 14:09:38 +02:00
{
foreach (var list in DataRoot.ChannelLists)
2013-03-31 14:09:38 +02:00
{
foreach (var channel in list.Channels)
channel.ChangeEncoding(this.DefaultEncoding);
2013-03-31 14:09:38 +02:00
}
}
#endregion
// TvSettingsForm
2013-03-31 14:09:38 +02:00
#region GetFileInformation()
public override string GetFileInformation()
2013-03-31 14:09:38 +02:00
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("ANALOG");
sb.Append("Number of data records: ").Append(this.analogChannelCount).AppendLine();
sb.Append("Length of data record: ").Append(this.actChannelSize).AppendLine();
sb.AppendLine();
sb.AppendLine();
sb.AppendLine("DVB-C/T");
sb.Append("Number of data records: ").Append(this.dvbctChannelCount).AppendLine();
sb.Append("Length of data record: ").Append(this.actChannelSize).AppendLine();
sb.AppendLine();
sb.AppendLine();
sb.AppendLine("DVB-S");
if (satConfig != null)
2013-03-31 14:09:38 +02:00
{
int numberOfDupePrNr;
CountDuplicateRecords(out numberOfDupePrNr);
sb.Append("Max number of data records: ").Append(satConfig.dvbsMaxChannelCount).AppendLine();
sb.Append("Length of data record: ").Append(satConfig.dvbsChannelLength).AppendLine();
sb.Append("Channel records in use: ").Append(dvbsChannelCount).AppendLine();
sb.Append("Channel records marked hard-deleted: ").Append(this.deletedChannelsHard).AppendLine();
sb.Append("Channel records marked soft-deleted: ").Append(this.deletedChannelsSoft).AppendLine();
sb.Append("Channel records erased (duplicates): ").Append(this.duplicateChannels).AppendLine();
sb.Append("Channel records with Pr# 0: ").Append(dvbsChannelsAtPr0).AppendLine();
sb.Append("Channel records with duplicate Pr#: ").Append(numberOfDupePrNr).AppendLine();
2013-03-31 14:09:38 +02:00
}
else
sb.AppendLine("not present");
2013-03-31 14:09:38 +02:00
return sb.ToString();
}
private void CountDuplicateRecords(out int numberOfDupePrNr)
{
numberOfDupePrNr = 0;
foreach (var list in this.DataRoot.ChannelLists)
{
if ((list.SignalSource & SignalSource.Sat) != 0)
numberOfDupePrNr += list.DuplicateProgNrCount;
}
}
#endregion
#region TvCountryCode
public string TvCountryCode
2013-03-31 14:09:38 +02:00
{
get { return this.countryCode; }
set
{
if (value.Length < 3 || this.settingsBlockOffset == 0 || this.settingsBlockSize < 8) return;
2013-03-31 14:09:38 +02:00
value = value.ToUpper();
int off = this.settingsBlockOffset + 4 + 4 + 2;
for (int i = 0; i < 3; i++)
this.fileContent[off--] = (byte)value[i];
2013-03-31 14:09:38 +02:00
this.countryCode = value;
}
}
#endregion
#region ShowDeviceSettingsForm()
public override void ShowDeviceSettingsForm(object parentWindow)
{
using (var dlg = new TvSettingsForm(this))
{
dlg.ShowDialog((Form)parentWindow);
2013-03-31 14:09:38 +02:00
}
}
#endregion
#region GetFirmwareMapping()
public FirmwareData GetFirmwareMapping()
{
var mapping = this.firmwareMappings.GetMapping(this.firmwareBlockSize, false);
if (mapping == null) return null;
mapping.SetDataPtr(this.fileContent, this.firmwareBlockOffset);
return mapping;
}
#endregion
2013-03-31 14:09:38 +02:00
// Testing
2013-03-31 14:09:38 +02:00
#region GetHotelMenuOffset()
public int GetHotelMenuOffset()
2013-03-31 14:09:38 +02:00
{
int off = this.firmwareBlockOffset;
for (int i = 6500; i < this.FirmwareBlockSize - 3; i++)
{
if (BitConverter.ToUInt32(this.fileContent, off + i) == 0x05000101) // 1,1,0,5
{
for (int j = 5; j < 20; j++) // backtrack to find Volume/MaxVolue pattern
{
if (fileContent[off + i - j] == 101 && fileContent[off + i - j - 6] == 100)
// check for Volume/MaxVolue to be 101/100
return this.firmwareBlockOffset + i - j - 15;
}
return -1;
}
}
return -1;
2013-03-31 14:09:38 +02:00
}
#endregion
2013-03-31 14:09:38 +02:00
internal int ACTChannelLength { get { return this.actChannelSize; } }
internal bool HasDvbs { get { return dvbsBlockOffset != 0; } }
internal int SatChannelLength { get { return satConfig != null ? satConfig.dvbsChannelLength : 0; } }
internal bool SatSymbolRateDiv2 { get { return this.isDvbsSymbolRateDiv2; } }
internal int FirmwareBlockSize { get { return this.firmwareBlockSize; } }
2013-03-31 14:09:38 +02:00
}
}