finished DVB-C and DVB-S2 implementation of Philips BIN format with Repair / channellib/*Table and s2channellib/*.dat format

This commit is contained in:
Horst Beham
2020-08-10 11:27:05 +02:00
parent bfc12eae66
commit df5d8770be
9 changed files with 444 additions and 137 deletions

View File

@@ -64,6 +64,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Channel.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Serializer.cs" /> <Compile Include="Serializer.cs" />
<Compile Include="SerializerPlugin.cs" /> <Compile Include="SerializerPlugin.cs" />

View File

@@ -17,3 +17,28 @@ lenName=32
offProvider=60 offProvider=60
lenProvider=32 lenProvider=32
[CableDigSrvTable_entry]
offChecksum=0
offSymbolRate=24
offFreqTimes16=48
offOnid=50
offSid=52
offTsid=54
offProgNr=122
offLocked=146
offIsFav=147
offName=216
lenName=64
[CablePresetTable_entry]
offChecksum=0
offFreqTimes16=4
offProgNr=8
offOnid=14
offTsid=16
offSid=18
[CableFrqMapTable_entry]
offChecksum=0
offSymbolRate=8
offFreq=18

View File

@@ -0,0 +1,16 @@
using ChanSort.Api;
namespace ChanSort.Loader.PhilipsBin
{
class Channel : ChannelInfo
{
public Channel(SignalSource source, long index, int oldProgNr, string name) : base(source, index, oldProgNr, name)
{
}
/// <summary>
/// index of the record in the AntennaPresetTable / CablePresetTable file for the channel, matched by (onid + tsid + sid)
/// </summary>
public int PresetTableIndex { get; set; } = -1;
}
}

View File

@@ -3,16 +3,19 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Schema;
using ChanSort.Api; using ChanSort.Api;
namespace ChanSort.Loader.PhilipsBin namespace ChanSort.Loader.PhilipsBin
{ {
/* /*
channellib\CableDigSrvTable:
===========================
Channels in this file are not phyiscally ordered by the program number and there is no linked list with prev/next indexes.
When editing a channel with the Philips Channel Editor, it only updates the progNr field (and overwrites all trailing bytes of the channel name with 0x00).
There is also the CablePresetTable file which is probably used for LCN. The Philips tool also updates the progNr in that file and uses it as is primary source
for the progNr. I don't know if there is a direct reference from the channel to the preset, hence this code uses the combination of ONID+TSID+SID to link the two.
s2channellib\service.dat: s2channellib\service.dat:
======================== ========================
All observed files have a perfectly linear next/prev table. The Philips Channel Editor also keeps that list linear and physically reorders the channel records. All observed files have a perfectly linear next/prev table. The Philips Channel Editor also keeps that list linear and physically reorders the channel records.
@@ -27,17 +30,20 @@ namespace ChanSort.Loader.PhilipsBin
When swapping satellite channels 1 and 2 with the Philips Channel Editor 6.62, it only updates a few fields and leaves the rest stale. When swapping satellite channels 1 and 2 with the Philips Channel Editor 6.62, it only updates a few fields and leaves the rest stale.
updated: SID, transponderIndex, channelName, providerName updated: SID, transponderIndex, channelName, providerName
This code here copyies the whole record before updating the fields This code here copies the whole record before updating the fields.
The favorite.dat file stores favorites as linked list which may support independent ordering from the main channel list.
The Philips editor even saves non-linear lists, but not in any particular order.
*/ */
class Serializer : SerializerBase class Serializer : SerializerBase
{ {
private readonly IniFile ini; private readonly IniFile ini;
private readonly List<string> dataFilePaths = new List<string>(); private readonly List<string> dataFilePaths = new List<string>();
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbCT, "DVB-T"); private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT, "DVB-T");
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbCT, "DVB-C"); private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC, "DVB-C");
private readonly ChannelList satChannels = new ChannelList(SignalSource.DvbS, "DVB-S"); private readonly ChannelList satChannels = new ChannelList(SignalSource.DvbS, "DVB-S");
#region ctor() #region ctor()
public Serializer(string inputFile) : base(inputFile) public Serializer(string inputFile) : base(inputFile)
{ {
@@ -49,7 +55,7 @@ namespace ChanSort.Loader.PhilipsBin
this.Features.CanSaveAs = false; this.Features.CanSaveAs = false;
this.Features.CanHaveGaps = false; this.Features.CanHaveGaps = false;
this.Features.SupportedFavorites = Favorites.A; this.Features.SupportedFavorites = Favorites.A;
this.Features.SortedFavorites = true; this.Features.SortedFavorites = false; // satellite favorites are stored in a separate file that may support independent sorting, but DVB C/T only have a flag
this.Features.AllowGapsInFavNumbers = false; this.Features.AllowGapsInFavNumbers = false;
this.Features.CanEditFavListNames = false; this.Features.CanEditFavListNames = false;
@@ -61,17 +67,20 @@ namespace ChanSort.Loader.PhilipsBin
{ {
list.VisibleColumnFieldNames.Remove("Skip"); list.VisibleColumnFieldNames.Remove("Skip");
list.VisibleColumnFieldNames.Remove("ShortName"); list.VisibleColumnFieldNames.Remove("ShortName");
list.VisibleColumnFieldNames.Remove("ServiceTypeName");
list.VisibleColumnFieldNames.Remove("Hidden");
list.VisibleColumnFieldNames.Remove("AudioPid");
list.VisibleColumnFieldNames.Remove("Encrypted");
} }
var supportedColumns = new[] {"OldPosition", "Position", "Name", "Lock"}; foreach (var list in new[] {dvbcChannels, dvbtChannels})
//this.satChannels.VisibleColumnFieldNames.Clear(); {
//foreach(var supportedColumn in supportedColumns) list.VisibleColumnFieldNames.Remove("PcrPid");
// this.satChannels.VisibleColumnFieldNames.Add(supportedColumn); list.VisibleColumnFieldNames.Remove("VideoPid");
list.VisibleColumnFieldNames.Remove("AudioPid");
this.satChannels.VisibleColumnFieldNames.Remove("AudioPid"); list.VisibleColumnFieldNames.Remove("ChannelOrTransponder");
this.satChannels.VisibleColumnFieldNames.Remove("ServiceTypeName"); list.VisibleColumnFieldNames.Remove("Provider");
this.satChannels.VisibleColumnFieldNames.Remove("Encrypted"); }
this.satChannels.VisibleColumnFieldNames.Remove("Hidden");
string iniFile = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".ini"); string iniFile = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".ini");
this.ini = new IniFile(iniFile); this.ini = new IniFile(iniFile);
@@ -87,32 +96,43 @@ namespace ChanSort.Loader.PhilipsBin
+ "ChannelList\\channellib\\CableDigSrvTable\n" + "ChannelList\\channellib\\CableDigSrvTable\n"
+ "ChannelList\\s2channellib\\service.dat"); + "ChannelList\\s2channellib\\service.dat");
var dir = Path.GetDirectoryName(this.FileName); var dir = Path.GetDirectoryName(this.FileName) ?? "";
LoadDvbCT(dvbtChannels, Path.Combine(dir, "channellib", "AntennaDigSrvTable")); var channellib = Path.Combine(dir, "channellib");
LoadDvbCT(dvbcChannels, Path.Combine(dir, "channellib", "CableDigSrvTable")); var s2channellib = Path.Combine(dir, "s2channellib");
LoadDvbsSatellites(Path.Combine(dir, "s2channellib", "satellite.dat")); // channellib files for DVB-C/T
LoadDvbsTransponders(Path.Combine(dir, "s2channellib", "tuneinfo.dat")); LoadDvbCT(dvbtChannels, Path.Combine(channellib, "AntennaDigSrvTable"));
LoadDvbS(satChannels, Path.Combine(dir, "s2channellib", "service.dat")); LoadDvbCTPresets(dvbtChannels, Path.Combine(channellib, "AntennaPresetTable"));
LoadDvbsFavorites(Path.Combine(dir, "s2channellib", "favorite.dat")); LoadDvbCT(dvbcChannels, Path.Combine(channellib, "CableDigSrvTable"));
var db_file_info = Path.Combine(dir, "s2channellib", "db_file_info.dat"); LoadDvbCTPresets(dvbcChannels, Path.Combine(channellib, "CablePresetTable"));
// s2channellib files for DVB-S
LoadDvbsSatellites(Path.Combine(s2channellib, "satellite.dat"));
LoadDvbsTransponders(Path.Combine(s2channellib, "tuneinfo.dat"));
LoadDvbS(satChannels, Path.Combine(s2channellib, "service.dat"));
LoadDvbsFavorites(Path.Combine(s2channellib, "favorite.dat"));
var db_file_info = Path.Combine(s2channellib, "db_file_info.dat");
if (File.Exists(db_file_info)) if (File.Exists(db_file_info))
this.dataFilePaths.Add(db_file_info); this.dataFilePaths.Add(db_file_info);
// for a proper ChanSort backup/restore with .bak files, the Philips _backup.dat files must also be included // for a proper ChanSort backup/restore with .bak files, the Philips _backup.dat files must also be included
foreach(var file in this.dataFilePaths.ToList()) foreach (var file in this.dataFilePaths.ToList())
this.dataFilePaths.Add(file.Replace(".dat", "_backup.dat")); {
if (file.Contains(".dat"))
this.dataFilePaths.Add(file.Replace(".dat", "_backup.dat"));
}
} }
#endregion #endregion
#region SetFileNameToChanLstBin() #region SetFileNameToChanLstBin()
private bool SetFileNameToChanLstBin() private bool SetFileNameToChanLstBin()
{ {
var dir = Path.GetDirectoryName(this.FileName); var dir = Path.GetDirectoryName(this.FileName) ?? "";
var dirName = Path.GetFileName(dir); var dirName = Path.GetFileName(dir);
if (StringComparer.InvariantCultureIgnoreCase.Compare(dirName, "channellib") == 0 || StringComparer.InvariantCultureIgnoreCase.Compare(dirName, "s2channellib") == 0) if (StringComparer.InvariantCultureIgnoreCase.Compare(dirName, "channellib") == 0 || StringComparer.InvariantCultureIgnoreCase.Compare(dirName, "s2channellib") == 0)
{ {
dir = Path.GetDirectoryName(dir); dir = Path.GetDirectoryName(dir) ?? "";
dirName = Path.GetFileName(dir); dirName = Path.GetFileName(dir);
} }
@@ -134,52 +154,110 @@ namespace ChanSort.Loader.PhilipsBin
#endregion #endregion
#region LoadDvbCT #region LoadDvbCT
private byte[] LoadDvbCT(ChannelList list, string path) private void LoadDvbCT(ChannelList list, string path)
{ {
if (!ReadAndValidateChannellibFile(path, out var data, out var recordSize, out var recordCount))
return;
var mapping = new DataMapping(this.ini.GetSection("CableDigSrvTable_entry"));
mapping.SetDataPtr(data, 20);
for (int i = 0; i < recordCount; i++, mapping.BaseOffset += recordSize)
{
var progNr = mapping.GetWord("offProgNr");
var offChannelName = mapping.BaseOffset + mapping.GetConst("offName", 0);
var lenName = mapping.GetConst("lenName", 0);
for (int j = 0; j < lenName; j += 2)
{
if (data[offChannelName + j] == 0)
{
lenName = j;
break;
}
}
string channelName = Encoding.Unicode.GetString(data, offChannelName, lenName);
var checksum = mapping.GetDword("offChecksum");
mapping.SetDword("offChecksum", 0);
var crc = FaultyCrc32(data, mapping.BaseOffset + mapping.GetConst("offChecksum", 0), recordSize);
if (crc != checksum)
throw new FileLoadException($"Invalid CRC in record {i} in {path}");
var ch = new Channel(list.SignalSource, i, progNr, channelName);
ch.FreqInMhz = (decimal) mapping.GetWord("offFreqTimes16") / 16;
ch.OriginalNetworkId = mapping.GetWord("offOnid");
ch.TransportStreamId = mapping.GetWord("offTsid");
ch.ServiceId = mapping.GetWord("offSid");
ch.SymbolRate = (int)mapping.GetDword("offSymbolRate") / 1000;
ch.Lock = mapping.GetByte("offLocked") != 0;
ch.Favorites = mapping.GetByte("offIsFav") != 0 ? Favorites.A : 0;
if (ch.Favorites != 0)
ch.OldFavIndex[0] = ch.OldProgramNr;
this.DataRoot.AddChannel(list, ch);
}
}
#endregion
#region LoadDvbCTPresets
private void LoadDvbCTPresets(ChannelList list, string path)
{
if (!ReadAndValidateChannellibFile(path, out var data, out var recordSize, out var recordCount))
return;
// build a mapping of (onid,tsid,sid) => channel
var channelById = new Dictionary<ulong, Channel>();
foreach(var chan in list.Channels)
{
var ch = (Channel)chan;
var id = ((ulong)ch.OriginalNetworkId << 32) | ((ulong)ch.TransportStreamId << 16) | (uint)ch.ServiceId;
channelById[id] = ch;
}
// apply preset progNr (LCN?) to the channel and remember the preset index for it
var mapping = new DataMapping(this.ini.GetSection("CablePresetTable_entry"));
mapping.SetDataPtr(data, 20);
for (int i = 0; i < recordCount; i++, mapping.BaseOffset += recordSize)
{
var onid = mapping.GetWord("offOnid");
var tsid = mapping.GetWord("offTsid");
var sid = mapping.GetWord("offSid");
var id = ((ulong)onid << 32) | ((ulong)tsid << 16) | sid;
if (!channelById.TryGetValue(id, out var ch))
continue;
ch.PresetTableIndex = i;
var progNr = mapping.GetWord("offProgNr");
if (progNr != 0 && progNr != 0xFFFF)
ch.OldProgramNr = progNr;
}
}
#endregion
#region ReadAndValidateChannellibFile
private bool ReadAndValidateChannellibFile(string path, out byte[] data, out int recordSize, out int recordCount)
{
data = null;
recordSize = 0;
recordCount = 0;
if (!File.Exists(path)) if (!File.Exists(path))
return null; return false;
var data = File.ReadAllBytes(path); data = File.ReadAllBytes(path);
if (data.Length < 20) if (data.Length < 20)
return null; return false;
var recordSize = BitConverter.ToInt32(data, 8); recordSize = BitConverter.ToInt32(data, 8);
var recordCount = BitConverter.ToInt32(data, 12); recordCount = BitConverter.ToInt32(data, 12);
if (data.Length != 20 + recordCount * recordSize) if (data.Length != 20 + recordCount * recordSize)
throw new FileLoadException("Unsupported file content: " + path); throw new FileLoadException("Unsupported file content: " + path);
this.dataFilePaths.Add(path); this.dataFilePaths.Add(path);
return true;
int baseOffset = 20;
for (int i = 0; i < recordCount; i++, baseOffset += recordSize)
{
uint checksum = BitConverter.ToUInt32(data, baseOffset + 0);
ushort progNr = BitConverter.ToUInt16(data, baseOffset + 122);
byte locked = data[baseOffset + 140];
int nameLen;
for (nameLen=0; nameLen<64; nameLen+=2)
if (data[baseOffset + 216 + nameLen] == 0)
break;
string channelName = Encoding.Unicode.GetString(data, baseOffset + 216, nameLen);
data[baseOffset + 0] = 0;
data[baseOffset + 1] = 0;
data[baseOffset + 2] = 0;
data[baseOffset + 3] = 0;
var crc = FaultyCrc32(data, baseOffset, recordSize);
if (crc != checksum)
throw new FileLoadException($"Invalid CRC in record {i} in {path}");
var ch = new ChannelInfo(list.SignalSource, i, progNr, channelName);
ch.Lock = locked != 0;
this.DataRoot.AddChannel(list, ch);
}
return data;
} }
#endregion
#endregion
#region LoadDvbsSatellites() #region LoadDvbsSatellites()
private void LoadDvbsSatellites(string path) private void LoadDvbsSatellites(string path)
@@ -397,13 +475,70 @@ namespace ChanSort.Loader.PhilipsBin
#region Save() #region Save()
public override void Save(string tvOutputFile) public override void Save(string tvOutputFile)
{ {
var dir = Path.GetDirectoryName(this.FileName); var dir = Path.GetDirectoryName(this.FileName) ?? "";
var channellib = Path.Combine(dir, "channellib");
var s2channellib = Path.Combine(dir, "s2channellib");
// TODO: save cable and antenna channels SaveDvbCTChannels(this.dvbtChannels, Path.Combine(channellib, "AntennaDigSrvTable"));
SaveDvbCTPresets(this.dvbtChannels, Path.Combine(channellib, "AntennaPresetTable"));
SaveDvbCTChannels(this.dvbcChannels, Path.Combine(channellib, "CableDigSrvTable"));
SaveDvbCTPresets(this.dvbcChannels, Path.Combine(channellib, "CablePresetTable"));
SaveDvbsChannels(Path.Combine(dir, "s2channellib", "service.dat")); SaveDvbsChannels(Path.Combine(s2channellib, "service.dat"));
SaveDvbsFavorites(Path.Combine(dir, "s2channellib", "favorite.dat")); SaveDvbsFavorites(Path.Combine(s2channellib, "favorite.dat"));
SaveDvbsDbFileInfo(Path.Combine(dir, "s2channellib", "db_file_info.dat")); SaveDvbsDbFileInfo(Path.Combine(s2channellib, "db_file_info.dat"));
}
#endregion
#region SaveDvbCTChannels
private void SaveDvbCTChannels(ChannelList list, string path)
{
if (!ReadAndValidateChannellibFile(path, out var data, out var recordSize, out _))
return;
var mapping = new DataMapping(this.ini.GetSection("CableDigSrvTable_entry"));
mapping.SetDataPtr(data, 20);
foreach (var ch in list.Channels)
{
mapping.BaseOffset = 20 + (int)ch.RecordIndex * recordSize;
mapping.SetWord("offProgNr", ch.NewProgramNr);
mapping.SetByte("offLocked", ch.Lock ? 1 : 0);
mapping.SetByte("offIsFav", ch.Favorites == 0 ? 0 : 1);
mapping.SetDword("offChecksum", 0);
var crc = FaultyCrc32(data, mapping.BaseOffset, recordSize);
mapping.SetDword("offChecksum", crc);
}
File.WriteAllBytes(path, data);
}
#endregion
#region SaveDvbCTPresets
private void SaveDvbCTPresets(ChannelList list, string path)
{
if (!ReadAndValidateChannellibFile(path, out var data, out var recordSize, out _))
return;
var mapping = new DataMapping(this.ini.GetSection("CablePresetTable_entry"));
mapping.SetDataPtr(data, 20);
// update the preset records with new channel numbers
foreach (var chan in list.Channels)
{
if (!(chan is Channel ch) || ch.PresetTableIndex < 0)
continue;
mapping.BaseOffset = 20 + ch.PresetTableIndex * recordSize;
mapping.SetWord("offProgNr", ch.NewProgramNr);
mapping.SetDword("offChecksum", 0);
var crc = FaultyCrc32(data, mapping.BaseOffset, recordSize);
mapping.SetDword("offChecksum", crc);
}
File.WriteAllBytes(path, data);
} }
#endregion #endregion

View File

@@ -1,5 +1,9 @@
#include "chansort.h" #include "chansort.h"
/***********************************************************
* s2channellib / DVB-S files
***********************************************************/
struct Ph_NextPrevTableEntry struct Ph_NextPrevTableEntry
{ {
word next; word next;
@@ -134,43 +138,131 @@ public struct Ph_FavoriteDat
dword crc32; dword crc32;
}; };
/***********************************************************
* channellib / antenna and cable files
***********************************************************/
public struct Ph_CableDigSrvTable public struct Ph_CableDigSrvTable
{ {
byte unk1[8]; dword unk1;
dword unk2;
dword chRecordSize; dword chRecordSize;
dword channelCount; dword channelCount;
byte unk2[4]; dword versionCode;
struct Ph_CableChannel struct Ph_CableChannel
{ {
var off0 = current_offset; var off0 = current_offset;
dword checksum; dword checksum;
byte unk1[110]; byte unk1[20];
dword symbolRate;
byte unk2[20];
struct
{
word subFreq : 4;
word mhz : 12;
} freqTimes16;
word onid;
word sid;
word tsid;
byte unk3b[58];
word progNrMostly;
byte unk4[6];
word progNr; word progNr;
byte unk2[6]; byte unk5[22];
word progNr2;
byte unk2b[16];
byte locked; byte locked;
byte unk3[75]; byte isFav;
byte unk6[68];
wchar_t channelName[32]; wchar_t channelName[32];
byte unk4[chRecordSize - (current_offset - off0)]; byte unk4[chRecordSize - (current_offset - off0)];
} Channels[channelCount]; } Channels[channelCount];
}; };
public struct Ph_CablePresetTable public struct Ph_CableDigTSTable
{ {
byte unk1[8]; dword unk1;
dword unk2;
dword recordSize; dword recordSize;
dword recordCount; dword recordCount;
byte unk2[4]; dword versionCode;
struct Ph_CableChannel
{
var off0 = current_offset;
dword checksum;
dword unk1;
dword unk2;
struct
{
dword subFreq :4;
dword mhz : 28;
} freqInMhzTimes16a;
dword unk3;
dword unk4;
dword unk5;
dword symbolRate;
dword unk6;
dword unk7;
struct
{
dword subFreq :4;
dword mhz : 28;
} freqInMhzTimes16b;
word onid;
word nid;
word tsid;
word unk10;
byte unk4[recordSize - (current_offset - off0)];
} Transponders[recordCount];
};
public struct Ph_CableFrqMapTable
{
dword unk1;
dword unk2;
dword recordSize;
dword recordCount;
dword versionCode;
struct
{
var off0 = current_offset;
dword checksum;
struct
{
dword subFreq :4;
dword mhz : 28;
} freqInMhzTimes16;
dword symbolRate;
dword unk2;
word onid;
word tsid;
word unk5;
word unk6;
dword unk7;
byte unk[recordSize - (current_offset - off0)];
} Transponders[recordCount];
};
public struct Ph_CablePresetTable
{
dword unk1;
dword unk2;
dword recordSize;
dword recordCount;
dword versionCode;
struct struct
{ {
var off0 = current_offset; var off0 = current_offset;
byte unk1[12]; dword checksum;
word unk2; struct
{
dword subFreq :4;
dword mhz : 28;
} freqInMhzTimes16;
word progNr;
word unk3; word unk3;
word unk4; word unk4;
word unk5; word onid;
word tsid;
word sid;
byte unk[recordSize - (current_offset - off0)]; byte unk[recordSize - (current_offset - off0)];
} ChanPreset[recordCount]; } ChanPreset[recordCount];
}; };

View File

@@ -0,0 +1,37 @@
using System;
using System.IO;
using System.Linq;
using ChanSort.Api;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test.Loader.PhilipsBin
{
[TestClass]
public class PhilipsChannellibTest
{
[TestMethod]
public void TestFiles1()
{
var baseDir = Path.GetDirectoryName(this.GetType().Assembly.Location);
var baseFile = Path.Combine(baseDir, "TestFiles1\\Repair\\ChannelList\\chanLst.bin");
var plugin = new ChanSort.Loader.PhilipsBin.SerializerPlugin();
var loader = plugin.CreateSerializer(baseFile);
loader.Load();
var list = loader.DataRoot.GetChannelList(SignalSource.DvbC);
Assert.AreEqual(179, list.Channels.Count);
Assert.AreEqual(179, list.Channels.Count(ch => !ch.IsDeleted));
var ch0 = list.Channels.FirstOrDefault(ch => ch.RecordIndex == 0);
Assert.AreEqual(41, ch0.OldProgramNr);
Assert.AreEqual("Passion HD", ch0.Name);
Assert.IsFalse(ch0.Lock);
Assert.AreEqual((Favorites)0, ch0.Favorites);
Assert.AreEqual(810, ch0.FreqInMhz);
Assert.AreEqual(9999, ch0.OriginalNetworkId);
Assert.AreEqual(461, ch0.TransportStreamId);
Assert.AreEqual(46102, ch0.ServiceId);
Assert.AreEqual(6900, ch0.SymbolRate);
}
}
}

View File

@@ -69,172 +69,173 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="PhilipsChannellibTest.cs" />
<Compile Include="PhilipsS2channellibTest.cs" /> <Compile Include="PhilipsS2channellibTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="TestFiles1\Repair\ChannelList\chanLst.bin"> <None Include="TestFiles1\Repair\ChannelList\chanLst.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaAnalogTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\AntennaAnalogTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaDigSrvTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\AntennaDigSrvTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaDigTSTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\AntennaDigTSTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaFrqMapTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\AntennaFrqMapTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaPresetTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\AntennaPresetTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\CableAnalogTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\CableAnalogTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\CableDigSrvTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\CableDigSrvTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\CableDigTSTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\CableDigTSTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\CableFrqMapTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\CableFrqMapTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\channellib\CablePresetTable"> <None Include="TestFiles1\Repair\ChannelList\channellib\CablePresetTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\adk_user_pref.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\adk_user_pref.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\adk_user_pref_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\adk_user_pref_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\db_file_info.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\db_file_info.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\db_file_info_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\db_file_info_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\favorite.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\favorite.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\favorite_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\favorite_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\lnb.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\lnb.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\lnb_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\lnb_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\satellite.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\satellite.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\satellite_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\satellite_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\service.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\service.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\service_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\service_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\tuneinfo.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\tuneinfo.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\tuneinfo_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\tuneinfo_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\user_pref.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\user_pref.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles1\Repair\ChannelList\s2channellib\user_pref_backup.dat"> <None Include="TestFiles1\Repair\ChannelList\s2channellib\user_pref_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\chanLst.bin"> <None Include="TestFiles2\Repair\ChannelList\chanLst.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaAnalogTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\AntennaAnalogTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaDigSrvTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\AntennaDigSrvTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaDigTSTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\AntennaDigTSTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaFrqMapTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\AntennaFrqMapTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaPresetTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\AntennaPresetTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\CableAnalogTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\CableAnalogTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\CableDigSrvTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\CableDigSrvTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\CableDigTSTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\CableDigTSTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\CableFrqMapTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\CableFrqMapTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\channellib\CablePresetTable"> <None Include="TestFiles2\Repair\ChannelList\channellib\CablePresetTable">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\adk_user_pref.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\adk_user_pref.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\adk_user_pref_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\adk_user_pref_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\db_file_info.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\db_file_info.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\db_file_info_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\db_file_info_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\favorite.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\favorite.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\favorite_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\favorite_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\lnb.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\lnb.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\lnb_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\lnb_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\satellite.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\satellite.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\satellite_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\satellite_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\service.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\service.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\service_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\service_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\tuneinfo.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\tuneinfo.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\tuneinfo_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\tuneinfo_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\user_pref.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\user_pref.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="TestFiles2\Repair\ChannelList\s2channellib\user_pref_backup.dat"> <None Include="TestFiles2\Repair\ChannelList\s2channellib\user_pref_backup.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>