mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-13 19:02:05 +01:00
finished DVB-C and DVB-S2 implementation of Philips BIN format with Repair / channellib/*Table and s2channellib/*.dat format
This commit is contained in:
@@ -64,6 +64,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Channel.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Serializer.cs" />
|
||||
<Compile Include="SerializerPlugin.cs" />
|
||||
|
||||
@@ -17,3 +17,28 @@ lenName=32
|
||||
offProvider=60
|
||||
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
|
||||
16
source/ChanSort.Loader.PhilipsBin/Channel.cs
Normal file
16
source/ChanSort.Loader.PhilipsBin/Channel.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,19 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using ChanSort.Api;
|
||||
|
||||
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:
|
||||
========================
|
||||
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.
|
||||
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
|
||||
{
|
||||
private readonly IniFile ini;
|
||||
private readonly List<string> dataFilePaths = new List<string>();
|
||||
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbCT, "DVB-T");
|
||||
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbCT, "DVB-C");
|
||||
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT, "DVB-T");
|
||||
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC, "DVB-C");
|
||||
private readonly ChannelList satChannels = new ChannelList(SignalSource.DvbS, "DVB-S");
|
||||
|
||||
|
||||
#region ctor()
|
||||
public Serializer(string inputFile) : base(inputFile)
|
||||
{
|
||||
@@ -49,7 +55,7 @@ namespace ChanSort.Loader.PhilipsBin
|
||||
this.Features.CanSaveAs = false;
|
||||
this.Features.CanHaveGaps = false;
|
||||
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.CanEditFavListNames = false;
|
||||
|
||||
@@ -61,17 +67,20 @@ namespace ChanSort.Loader.PhilipsBin
|
||||
{
|
||||
list.VisibleColumnFieldNames.Remove("Skip");
|
||||
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"};
|
||||
//this.satChannels.VisibleColumnFieldNames.Clear();
|
||||
//foreach(var supportedColumn in supportedColumns)
|
||||
// this.satChannels.VisibleColumnFieldNames.Add(supportedColumn);
|
||||
|
||||
this.satChannels.VisibleColumnFieldNames.Remove("AudioPid");
|
||||
this.satChannels.VisibleColumnFieldNames.Remove("ServiceTypeName");
|
||||
this.satChannels.VisibleColumnFieldNames.Remove("Encrypted");
|
||||
this.satChannels.VisibleColumnFieldNames.Remove("Hidden");
|
||||
foreach (var list in new[] {dvbcChannels, dvbtChannels})
|
||||
{
|
||||
list.VisibleColumnFieldNames.Remove("PcrPid");
|
||||
list.VisibleColumnFieldNames.Remove("VideoPid");
|
||||
list.VisibleColumnFieldNames.Remove("AudioPid");
|
||||
list.VisibleColumnFieldNames.Remove("ChannelOrTransponder");
|
||||
list.VisibleColumnFieldNames.Remove("Provider");
|
||||
}
|
||||
|
||||
string iniFile = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".ini");
|
||||
this.ini = new IniFile(iniFile);
|
||||
@@ -87,32 +96,43 @@ namespace ChanSort.Loader.PhilipsBin
|
||||
+ "ChannelList\\channellib\\CableDigSrvTable\n"
|
||||
+ "ChannelList\\s2channellib\\service.dat");
|
||||
|
||||
var dir = Path.GetDirectoryName(this.FileName);
|
||||
LoadDvbCT(dvbtChannels, Path.Combine(dir, "channellib", "AntennaDigSrvTable"));
|
||||
LoadDvbCT(dvbcChannels, Path.Combine(dir, "channellib", "CableDigSrvTable"));
|
||||
var dir = Path.GetDirectoryName(this.FileName) ?? "";
|
||||
var channellib = Path.Combine(dir, "channellib");
|
||||
var s2channellib = Path.Combine(dir, "s2channellib");
|
||||
|
||||
LoadDvbsSatellites(Path.Combine(dir, "s2channellib", "satellite.dat"));
|
||||
LoadDvbsTransponders(Path.Combine(dir, "s2channellib", "tuneinfo.dat"));
|
||||
LoadDvbS(satChannels, Path.Combine(dir, "s2channellib", "service.dat"));
|
||||
LoadDvbsFavorites(Path.Combine(dir, "s2channellib", "favorite.dat"));
|
||||
var db_file_info = Path.Combine(dir, "s2channellib", "db_file_info.dat");
|
||||
// channellib files for DVB-C/T
|
||||
LoadDvbCT(dvbtChannels, Path.Combine(channellib, "AntennaDigSrvTable"));
|
||||
LoadDvbCTPresets(dvbtChannels, Path.Combine(channellib, "AntennaPresetTable"));
|
||||
LoadDvbCT(dvbcChannels, Path.Combine(channellib, "CableDigSrvTable"));
|
||||
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))
|
||||
this.dataFilePaths.Add(db_file_info);
|
||||
|
||||
// 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())
|
||||
this.dataFilePaths.Add(file.Replace(".dat", "_backup.dat"));
|
||||
foreach (var file in this.dataFilePaths.ToList())
|
||||
{
|
||||
if (file.Contains(".dat"))
|
||||
this.dataFilePaths.Add(file.Replace(".dat", "_backup.dat"));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SetFileNameToChanLstBin()
|
||||
private bool SetFileNameToChanLstBin()
|
||||
{
|
||||
var dir = Path.GetDirectoryName(this.FileName);
|
||||
var dir = Path.GetDirectoryName(this.FileName) ?? "";
|
||||
var dirName = Path.GetFileName(dir);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -134,52 +154,110 @@ namespace ChanSort.Loader.PhilipsBin
|
||||
#endregion
|
||||
|
||||
#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))
|
||||
return null;
|
||||
return false;
|
||||
|
||||
var data = File.ReadAllBytes(path);
|
||||
data = File.ReadAllBytes(path);
|
||||
if (data.Length < 20)
|
||||
return null;
|
||||
return false;
|
||||
|
||||
var recordSize = BitConverter.ToInt32(data, 8);
|
||||
var recordCount = BitConverter.ToInt32(data, 12);
|
||||
recordSize = BitConverter.ToInt32(data, 8);
|
||||
recordCount = BitConverter.ToInt32(data, 12);
|
||||
if (data.Length != 20 + recordCount * recordSize)
|
||||
throw new FileLoadException("Unsupported file content: " + path);
|
||||
|
||||
this.dataFilePaths.Add(path);
|
||||
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region LoadDvbsSatellites()
|
||||
private void LoadDvbsSatellites(string path)
|
||||
@@ -397,13 +475,70 @@ namespace ChanSort.Loader.PhilipsBin
|
||||
#region Save()
|
||||
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"));
|
||||
SaveDvbsFavorites(Path.Combine(dir, "s2channellib", "favorite.dat"));
|
||||
SaveDvbsDbFileInfo(Path.Combine(dir, "s2channellib", "db_file_info.dat"));
|
||||
SaveDvbsChannels(Path.Combine(s2channellib, "service.dat"));
|
||||
SaveDvbsFavorites(Path.Combine(s2channellib, "favorite.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
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "chansort.h"
|
||||
|
||||
/***********************************************************
|
||||
* s2channellib / DVB-S files
|
||||
***********************************************************/
|
||||
|
||||
struct Ph_NextPrevTableEntry
|
||||
{
|
||||
word next;
|
||||
@@ -134,43 +138,131 @@ public struct Ph_FavoriteDat
|
||||
dword crc32;
|
||||
};
|
||||
|
||||
/***********************************************************
|
||||
* channellib / antenna and cable files
|
||||
***********************************************************/
|
||||
|
||||
public struct Ph_CableDigSrvTable
|
||||
{
|
||||
byte unk1[8];
|
||||
dword unk1;
|
||||
dword unk2;
|
||||
dword chRecordSize;
|
||||
dword channelCount;
|
||||
byte unk2[4];
|
||||
dword versionCode;
|
||||
struct Ph_CableChannel
|
||||
{
|
||||
var off0 = current_offset;
|
||||
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;
|
||||
byte unk2[6];
|
||||
word progNr2;
|
||||
byte unk2b[16];
|
||||
byte unk5[22];
|
||||
byte locked;
|
||||
byte unk3[75];
|
||||
byte isFav;
|
||||
byte unk6[68];
|
||||
wchar_t channelName[32];
|
||||
byte unk4[chRecordSize - (current_offset - off0)];
|
||||
} Channels[channelCount];
|
||||
};
|
||||
|
||||
public struct Ph_CablePresetTable
|
||||
public struct Ph_CableDigTSTable
|
||||
{
|
||||
byte unk1[8];
|
||||
dword unk1;
|
||||
dword unk2;
|
||||
dword recordSize;
|
||||
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
|
||||
{
|
||||
var off0 = current_offset;
|
||||
byte unk1[12];
|
||||
word unk2;
|
||||
dword checksum;
|
||||
struct
|
||||
{
|
||||
dword subFreq :4;
|
||||
dword mhz : 28;
|
||||
} freqInMhzTimes16;
|
||||
word progNr;
|
||||
word unk3;
|
||||
word unk4;
|
||||
word unk5;
|
||||
word onid;
|
||||
word tsid;
|
||||
word sid;
|
||||
byte unk[recordSize - (current_offset - off0)];
|
||||
} ChanPreset[recordCount];
|
||||
};
|
||||
|
||||
37
source/Test.Loader.PhilipsBin/PhilipsChannellibTest.cs
Normal file
37
source/Test.Loader.PhilipsBin/PhilipsChannellibTest.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,172 +69,173 @@
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PhilipsChannellibTest.cs" />
|
||||
<Compile Include="PhilipsS2channellibTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="TestFiles1\Repair\ChannelList\chanLst.bin">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaAnalogTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaDigSrvTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaDigTSTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaFrqMapTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\AntennaPresetTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\CableAnalogTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\CableDigSrvTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\CableDigTSTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\CableFrqMapTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\channellib\CablePresetTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\adk_user_pref.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\adk_user_pref_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\db_file_info.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\db_file_info_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\favorite.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\favorite_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\lnb.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\lnb_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\satellite.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\satellite_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\service.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\service_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\tuneinfo.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\tuneinfo_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\user_pref.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles1\Repair\ChannelList\s2channellib\user_pref_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\chanLst.bin">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaAnalogTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaDigSrvTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaDigTSTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaFrqMapTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\AntennaPresetTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\CableAnalogTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\CableDigSrvTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\CableDigTSTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\CableFrqMapTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\channellib\CablePresetTable">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\adk_user_pref.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\adk_user_pref_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\db_file_info.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\db_file_info_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\favorite.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\favorite_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\lnb.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\lnb_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\satellite.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\satellite_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\service.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\service_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\tuneinfo.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\tuneinfo_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\user_pref.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="TestFiles2\Repair\ChannelList\s2channellib\user_pref_backup.dat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user