diff --git a/source/ChanSort.Api/Utils/DvbStringDecoder.cs b/source/ChanSort.Api/Utils/DvbStringDecoder.cs
index 1267956..1f9610f 100644
--- a/source/ChanSort.Api/Utils/DvbStringDecoder.cs
+++ b/source/ChanSort.Api/Utils/DvbStringDecoder.cs
@@ -90,7 +90,15 @@ namespace ChanSort.Api
public Encoding DefaultEncoding { get; set; }
#region GetChannelNames()
+
public void GetChannelNames(byte[] name, int off, int len, out string longName, out string shortName)
+ {
+ this.GetChannelNamesCore(name, off, len, out longName, out shortName);
+ longName = longName.TrimGarbage();
+ shortName = shortName.TrimGarbage();
+ }
+
+ private void GetChannelNamesCore(byte[] name, int off, int len, out string longName, out string shortName)
{
longName = "";
shortName = "";
diff --git a/source/ChanSort.Api/Utils/Tools.cs b/source/ChanSort.Api/Utils/Tools.cs
index 4c85962..fc71736 100644
--- a/source/ChanSort.Api/Utils/Tools.cs
+++ b/source/ChanSort.Api/Utils/Tools.cs
@@ -215,5 +215,14 @@ namespace ChanSort.Api
}
#endregion
+ public static string TrimGarbage(this string input)
+ {
+ if (input == null) return null;
+ var i = input.IndexOf('\0');
+ if (i >= 0)
+ return input.Substring(0, i);
+ return input;
+ }
+
}
}
diff --git a/source/ChanSort.Loader.Philips/BinarySerializer.cs b/source/ChanSort.Loader.Philips/BinarySerializer.cs
index 5f001b3..77be72d 100644
--- a/source/ChanSort.Loader.Philips/BinarySerializer.cs
+++ b/source/ChanSort.Loader.Philips/BinarySerializer.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Data;
+using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -9,6 +11,9 @@ using ChanSort.Api;
namespace ChanSort.Loader.Philips
{
/*
+
+ This loader handles the file format versions 1.x (*Table and *.dat files) and version 25.x-45.x (*Db.bin files)
+
channellib\CableDigSrvTable:
===========================
Channels in this file are not physically ordered by the program number and there is no linked list with prev/next indexes.
@@ -92,37 +97,42 @@ namespace ChanSort.Loader.Philips
#region Load()
public override void Load()
{
- if (!SetFileNameToChanLstBin())
- throw new FileLoadException("Unsupported folder structure. Required files are:\n"
- + "ChannelList\\chanLst.bin\n"
- + "ChannelList\\channellib\\CableDigSrvTable\n"
- + "ChannelList\\s2channellib\\service.dat");
-
this.chanLstBin = new ChanLstBin();
this.chanLstBin.Load(this.FileName, msg => this.logMessages.AppendLine(msg));
+ this.dataFilePaths.Add(this.FileName);
+
+ if (chanLstBin.VersionMajor >= 25 && chanLstBin.VersionMajor <= 45) // need VC2010 Redist for the SQLite library
+ DepencencyChecker.AssertVc2010RedistPackageX86Installed();
var dir = Path.GetDirectoryName(this.FileName) ?? "";
var channellib = Path.Combine(dir, "channellib");
var s2channellib = Path.Combine(dir, "s2channellib");
- // channellib files for DVB-C/T in version 1.1 and 1.2
- LoadDvbCT(dvbtChannels, Path.Combine(channellib, "AntennaDigSrvTable"), "CableDigSrvTable_entry");
- LoadDvbCTPresets(dvbtChannels, Path.Combine(channellib, "AntennaPresetTable"));
- LoadDvbCT(dvbcChannels, Path.Combine(channellib, "CableDigSrvTable"), "CableDigSrvTable_entry");
- LoadDvbCTPresets(dvbcChannels, Path.Combine(channellib, "CablePresetTable"));
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ LoadDvbCT(dvbtChannels, Path.Combine(channellib, "AntennaDigSrvTable"), "CableDigSrvTable_entry");
+ LoadDvbCTPresets(dvbtChannels, Path.Combine(channellib, "AntennaPresetTable"));
+ LoadDvbCT(dvbcChannels, Path.Combine(channellib, "CableDigSrvTable"), "CableDigSrvTable_entry");
+ LoadDvbCTPresets(dvbcChannels, Path.Combine(channellib, "CablePresetTable"));
- // s2channellib files for DVB-S in version 1.1 and 1.2
- LoadDvbsSatellites(Path.Combine(s2channellib, "satellite.dat"));
- LoadDvbsTransponders(Path.Combine(s2channellib, "tuneinfo.dat"));
- LoadDvbS(satChannels, Path.Combine(s2channellib, "service.dat"), "service.dat_entry");
- 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);
-
- // version 45
- if (chanLstBin.VersionMajor == 45)
- LoadDvbS(satChannels, Path.Combine(s2channellib, "SatelliteDb.bin"), "Map45_SatelliteDb_entry");
+ LoadDvbsSatellites(Path.Combine(s2channellib, "satellite.dat"));
+ LoadDvbsTransponders(Path.Combine(s2channellib, "tuneinfo.dat"));
+ LoadDvbS(satChannels, Path.Combine(s2channellib, "service.dat"), "service.dat_entry");
+ 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);
+ }
+ else if (chanLstBin.VersionMajor >= 25 && chanLstBin.VersionMajor <= 45)
+ {
+ // version 25-45
+ LoadDvbCT(dvbtChannels, Path.Combine(channellib, "TerrestrialDb.bin"), "Map45_CableDb.bin_entry");
+ LoadDvbCT(dvbcChannels, Path.Combine(channellib, "CableDb.bin"), "Map45_CableDb.bin_entry");
+ LoadDvbS(satChannels, Path.Combine(s2channellib, "SatelliteDb.bin"), "Map45_SatelliteDb.bin_entry");
+ var tvDbFile = Path.Combine(dir, "tv.db");
+ if (File.Exists(tvDbFile))
+ this.dataFilePaths.Add(tvDbFile);
+ }
// 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())
@@ -131,36 +141,8 @@ namespace ChanSort.Loader.Philips
this.dataFilePaths.Add(file.Replace(".dat", "_backup.dat"));
}
}
-
#endregion
- #region SetFileNameToChanLstBin()
- private bool SetFileNameToChanLstBin()
- {
- 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) ?? "";
- dirName = Path.GetFileName(dir);
- }
-
- if (StringComparer.InvariantCultureIgnoreCase.Compare(dirName, "ChannelList") != 0)
- return false;
-
- var chanLstBin = Path.Combine(dir, "chanLst.bin");
- if (!File.Exists(chanLstBin))
- return false;
-
- if (!File.Exists(Path.Combine(dir, "channellib", "CableDigSrvTable")))
- return false;
- if (!File.Exists(Path.Combine(dir, "s2channellib", "service.dat")))
- return false;
-
- this.FileName = chanLstBin; // this file is used as a fixed reference point for the whole directory structure
- return true;
- }
- #endregion
#region LoadDvbCT
private void LoadDvbCT(ChannelList list, string path, string mappingName)
@@ -169,7 +151,7 @@ namespace ChanSort.Loader.Philips
return;
var mapping = new DataMapping(this.ini.GetSection(mappingName));
- mapping.SetDataPtr(data, 20);
+ mapping.SetDataPtr(data, chanLstBin.VersionMajor <= 11 ? 20 : 12);
for (int i = 0; i < recordCount; i++, mapping.BaseOffset += recordSize)
{
@@ -187,13 +169,17 @@ namespace ChanSort.Loader.Philips
}
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}");
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ 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.Id = mapping.GetWord("offId"); // only relevant for ChannelMap45
ch.FreqInMhz = (decimal) mapping.GetWord("offFreqTimes16") / 16;
ch.OriginalNetworkId = mapping.GetWord("offOnid");
ch.TransportStreamId = mapping.GetWord("offTsid");
@@ -254,13 +240,27 @@ namespace ChanSort.Loader.Philips
return false;
data = File.ReadAllBytes(path);
- if (data.Length < 20)
- return false;
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ if (data.Length < 20)
+ return false;
+
+ recordSize = BitConverter.ToInt32(data, 8);
+ recordCount = BitConverter.ToInt32(data, 12);
+ if (data.Length != 20 + recordCount * recordSize)
+ throw new FileLoadException("Unsupported file content: " + path);
+ }
+ else
+ {
+ if (data.Length < 12)
+ return false;
+
+ recordSize = 156; // Map45
+ recordCount = BitConverter.ToInt32(data, 8);
+ if (data.Length != 12 + recordCount * recordSize)
+ throw new FileLoadException("Unsupported file content: " + path);
+ }
- 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);
return true;
@@ -296,7 +296,8 @@ namespace ChanSort.Loader.Philips
var s = new Satellite(i);
var pos = (sbyte)data[baseOffset + 8];
s.OrbitalPosition = pos < 0 ? -pos + "W" : pos + "E";
- s.Name = this.DefaultEncoding.GetString(data, baseOffset + 16, 16).TrimEnd('\0');
+ s.Name = this.DefaultEncoding.GetString(data, baseOffset + 16, 16).TrimGarbage();
+
this.DataRoot.AddSatellite(s);
}
}
@@ -350,10 +351,12 @@ namespace ChanSort.Loader.Philips
return;
var data = File.ReadAllBytes(path);
- if (data.Length < 4)
+ if (data.Length < 12)
return;
- if (chanLstBin.VersionMajor == 1)
+ var version = chanLstBin.VersionMajor;
+
+ if (version <= 11)
{
var checksum = BitConverter.ToUInt32(data, data.Length - 4);
@@ -366,8 +369,10 @@ namespace ChanSort.Loader.Philips
int recordSize = BitConverter.ToInt32(data, 4);
int recordCount = BitConverter.ToInt32(data, 8);
+ if (recordSize == 0 && version != 1)
+ recordSize = recordCount == 0 ? 0 : (data.Length - 12) / recordCount;
- if (chanLstBin.VersionMajor == 1)
+ if (chanLstBin.VersionMajor <= 11)
{
// 12 bytes header, then a "next/prev" table, then the service records, then a CRC32
// the "next/prev" table is a ring-list, every entry consists of 2 ushorts with the next and previous channel, wrapping around on the ends
@@ -380,7 +385,7 @@ namespace ChanSort.Loader.Philips
var dvbStringDecoder = new DvbStringDecoder(this.DefaultEncoding);
var mapping = new DataMapping(this.ini.GetSection(mappingName));
- mapping.SetDataPtr(data, 12 + recordCount * 4);
+ mapping.SetDataPtr(data, 12 + (chanLstBin.VersionMajor <= 11 ? recordCount * 4 : 0));
for (int i = 0; i < recordCount; i++, mapping.BaseOffset += recordSize)
{
var ch = LoadDvbsChannel(list, mapping, i, dvbStringDecoder);
@@ -394,7 +399,7 @@ namespace ChanSort.Loader.Philips
{
var transponderId = mapping.GetWord("offTransponderIndex");
var progNr = mapping.GetWord("offProgNr");
- var ch = new ChannelInfo(list.SignalSource, recordIndex, progNr, null);
+ var ch = new Channel(list.SignalSource, recordIndex, progNr, "");
// deleted channels must be kept in the list because their records must also be physically reordered when saving the list
if (progNr == 0xFFFF || transponderId == 0xFFFF)
@@ -413,14 +418,24 @@ namespace ChanSort.Loader.Philips
ch.VideoPid = mapping.GetWord("offVpid") & mapping.GetMask("maskVpid");
ch.Favorites = mapping.GetFlag("IsFav") ? Favorites.A : 0;
ch.OldProgramNr = progNr;
+ ch.Id = mapping.GetWord("offId"); // relevant for ChannelMap45
- // the 0x1F as the first byte of the channel name is likely the DVB encoding indicator for UTF-8. So we use the DvbStringDecoder here
- dvbStringDecoder.GetChannelNames(mapping.Data, mapping.BaseOffset + mapping.GetConst("offName", 0), mapping.GetConst("lenName", 0), out var longName, out var shortName);
- ch.Name = longName.TrimEnd('\0');
- ch.ShortName = shortName.TrimEnd('\0');
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ // the 0x1F as the first byte of the channel name is likely the DVB encoding indicator for UTF-8. So we use the DvbStringDecoder here
+ dvbStringDecoder.GetChannelNames(mapping.Data, mapping.BaseOffset + mapping.GetConst("offName", 0), mapping.GetConst("lenName", 0), out var longName, out var shortName);
+ ch.Name = longName;
+ ch.ShortName = shortName;
+ }
+ else
+ {
+ ch.Name = Encoding.Unicode.GetString(mapping.Data, mapping.BaseOffset + mapping.GetConst("offName", 0), mapping.GetConst("lenName", 0)).TrimEnd('\0');
+ ch.FreqInMhz = mapping.GetWord("offFreq");
+ ch.SymbolRate = (int)(mapping.GetDword("offSymbolRate") / 1000);
+ }
dvbStringDecoder.GetChannelNames(mapping.Data, mapping.BaseOffset + mapping.GetConst("offProvider", 0), mapping.GetConst("lenProvider", 0), out var provider, out _);
- ch.Provider = provider.TrimEnd('\0');
+ ch.Provider = provider;
// copy values from the satellite/transponder tables to the channel
if (this.DataRoot.Transponder.TryGetValue(transponderId, out var t))
@@ -495,14 +510,25 @@ namespace ChanSort.Loader.Philips
var channellib = Path.Combine(dir, "channellib");
var s2channellib = Path.Combine(dir, "s2channellib");
- 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"));
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ 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(s2channellib, "service.dat"));
- SaveDvbsFavorites(Path.Combine(s2channellib, "favorite.dat"));
- SaveDvbsDbFileInfo(Path.Combine(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"));
+ }
+ else if (chanLstBin.VersionMajor >= 25 && chanLstBin.VersionMajor <= 45)
+ {
+ SaveDvbCTChannels(this.dvbtChannels, Path.Combine(channellib, "TerrestrialDb.bin"));
+ SaveDvbCTChannels(this.dvbcChannels, Path.Combine(channellib, "CableDb.bin"));
+ SaveDvbsChannels(Path.Combine(s2channellib, "SatelliteDb.bin"));
+
+ UpdateChannelMap45TvDb();
+ }
this.chanLstBin.Save(this.FileName);
}
@@ -515,18 +541,38 @@ namespace ChanSort.Loader.Philips
if (!ReadAndValidateChannellibFile(path, out var data, out var recordSize, out _))
return;
- var mapping = new DataMapping(this.ini.GetSection("CableDigSrvTable_entry"));
- mapping.SetDataPtr(data, 20);
+ int baseOffset;
+ DataMapping mapping;
+
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ mapping = new DataMapping(this.ini.GetSection("CableDigSrvTable_entry"));
+ baseOffset = 20;
+ }
+ else
+ {
+ mapping = new DataMapping(this.ini.GetSection("Map45_CableDb.bin_entry"));
+ baseOffset = 12;
+ }
+ mapping.SetDataPtr(data, baseOffset);
foreach (var ch in list.Channels)
{
- mapping.BaseOffset = 20 + (int)ch.RecordIndex * recordSize;
+ if (ch.IsProxy) continue;
+ mapping.BaseOffset = baseOffset + (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);
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ mapping.SetDword("offChecksum", 0);
+ var crc = FaultyCrc32(data, mapping.BaseOffset, recordSize);
+ mapping.SetDword("offChecksum", crc);
+ }
+ else if (chanLstBin.VersionMajor >= 25 && chanLstBin.VersionMajor <= 45)
+ {
+ mapping.SetWord("offServiceEdit", 1);
+ }
}
File.WriteAllBytes(path, data);
@@ -564,16 +610,32 @@ namespace ChanSort.Loader.Philips
private void SaveDvbsChannels(string path)
{
var orig = File.ReadAllBytes(path);
- int recordSize = BitConverter.ToInt32(orig, 4);
- int recordCount = BitConverter.ToInt32(orig, 8);
-
+
// create a new array for the modified data, copying the header and next/prev table
var data = new byte[orig.Length];
- Array.Copy(orig, data, 12 + recordCount * 4);
- var baseOffset = 12 + recordCount * 4;
+ int recordCount = BitConverter.ToInt32(orig, 8);
+ int recordSize;
+ int baseOffset;
+ DataMapping mapping;
- var mapping = new DataMapping(this.ini.GetSection("service.dat_entry"));
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ recordSize = BitConverter.ToInt32(orig, 4);
+ baseOffset = 12 + recordCount * 4;
+ mapping = new DataMapping(this.ini.GetSection("service.dat_entry"));
+ }
+ else
+ {
+ recordSize = recordCount == 0 ? 0 : (orig.Length - 12) / recordCount;
+ baseOffset = 12;
+ mapping = new DataMapping(this.ini.GetSection("Map45_SatelliteDb.bin_entry"));
+ }
+
+ if (recordCount == 0)
+ return;
+
+ Array.Copy(orig, data, baseOffset);
mapping.SetDataPtr(data, baseOffset);
// copy physical records to bring them in the new order and update fields like progNr
@@ -594,18 +656,22 @@ namespace ChanSort.Loader.Philips
mapping.SetWord("offProgNr", ch.NewProgramNr);
mapping.SetFlag("IsFav", ch.Favorites != 0);
mapping.SetFlag("Locked", ch.Lock);
+ mapping.SetWord("offServiceEdit", 1);
}
ch.RecordIndex = i++; // required so that subsequent saves don't reshuffle the records
}
+ if (chanLstBin.VersionMajor <= 11)
+ {
+ var crc32 = ~Crc32.Reversed.CalcCrc32(data, 0, data.Length - 4);
+ data.SetInt32(data.Length - 4, (int) crc32);
+
+ var backupFile = path.Replace(".dat", "_backup.dat");
+ File.WriteAllBytes(backupFile, data);
+ }
- var crc32 = ~Crc32.Reversed.CalcCrc32(data, 0, data.Length - 4);
- data.SetInt32(data.Length-4, (int)crc32);
File.WriteAllBytes(path, data);
-
- var backupFile = path.Replace(".dat", "_backup.dat");
- File.WriteAllBytes(backupFile, data);
}
#endregion
@@ -667,6 +733,47 @@ namespace ChanSort.Loader.Philips
}
#endregion
+ #region UpdateChannelMap45TvDb()
+ private void UpdateChannelMap45TvDb()
+ {
+ var tvDb = Path.Combine(Path.GetDirectoryName(this.FileName) ?? "", "tv.db");
+ if (!File.Exists(tvDb))
+ return;
+
+ using var conn = new SQLiteConnection($"Data Source={tvDb}");
+ conn.Open();
+ using var trans = conn.BeginTransaction();
+ using var cmd = conn.CreateCommand();
+ cmd.CommandText = "update channels set display_number=@prNum, display_name=@name, browsable=@browsable, locked=@locked where _id=@id";
+ cmd.Parameters.Clear();
+ cmd.Parameters.Add(new SQLiteParameter("@id", DbType.Int32));
+ cmd.Parameters.Add(new SQLiteParameter("@prNum", DbType.Int32));
+ cmd.Parameters.Add(new SQLiteParameter("@name", DbType.String));
+ cmd.Parameters.Add(new SQLiteParameter("@browsable", DbType.Int32));
+ cmd.Parameters.Add(new SQLiteParameter("@locked", DbType.Int32));
+ cmd.Prepare();
+ foreach (var list in this.DataRoot.ChannelLists)
+ {
+ foreach (var chan in list.Channels)
+ {
+ if (!(chan is Channel ch))
+ continue;
+ cmd.Parameters["@id"].Value = ch.Id;
+ cmd.Parameters["@prNum"].Value = ch.NewProgramNr;
+ cmd.Parameters["@name"].Value = ch.Name;
+ cmd.Parameters["@browsable"].Value = ch.Skip ? 0 : 1;
+ cmd.Parameters["@locked"].Value = ch.Lock ? 1 : 0;
+
+ var res = cmd.ExecuteNonQuery();
+ if (res == 0)
+ this.logMessages.AppendFormat($"Could not update record with id {ch.Id} in tv.db service table");
+ }
+ }
+ trans.Commit();
+ conn.Close();
+ }
+ #endregion
+
#region FaultyCrc32
public static uint FaultyCrc32(byte[] bytes, int start, int count)
diff --git a/source/ChanSort.Loader.Philips/ChanLstBin.cs b/source/ChanSort.Loader.Philips/ChanLstBin.cs
index f71816d..95d70d1 100644
--- a/source/ChanSort.Loader.Philips/ChanLstBin.cs
+++ b/source/ChanSort.Loader.Philips/ChanLstBin.cs
@@ -54,7 +54,7 @@ namespace ChanSort.Loader.Philips
var modelNameLen = BitConverter.ToInt32(content, off);
off += 4 + modelNameLen;
- var baseDir = Path.GetDirectoryName(path);
+ var baseDir = Path.GetDirectoryName(path) ?? "";
var relPath = "/channellib/";
while (off < content.Length)
{
@@ -67,6 +67,7 @@ namespace ChanSort.Loader.Philips
else
{
// normally all files after the /s2channellib/ entry are inside that folder, but "Favorite.xml" is in the main folder
+ // in ChannelMap45 there is also tv.db and list.db in the main folder
var newPath = relPath + fileName;
if (!File.Exists(Path.Combine(baseDir, newPath)) && File.Exists(Path.Combine(baseDir, fileName)))
newPath = "/" + fileName;
@@ -92,9 +93,18 @@ namespace ChanSort.Loader.Philips
var filePath = baseDir + entry.Key;
if (!File.Exists(filePath))
+ {
+ errors += $"\nchanLst.bin: file not found in directory structure: {entry.Key}";
continue;
+ }
+
var data = File.ReadAllBytes(filePath);
- var length = Math.Min(data.Length, VersionMajor <= 12 ? 0x6000 : 0x145A00);
+ var length = data.Length;
+ if (VersionMajor < 12 && length > 0x6000)
+ length = 0x6000; // there might be another cap at 0x013FA000 + 0x6000 in some versions
+ //if (length > 0x0140000)
+ // length = 0x0140000;
+
var actualCrc = Crc16.Calc(data, 0, length);
if (actualCrc != expectedCrc)
{
@@ -104,10 +114,7 @@ namespace ChanSort.Loader.Philips
}
if (errors != "")
- {
- this.log.Invoke(errors);
- //throw new FileLoadException(errors);
- }
+ this.log?.Invoke(errors);
}
public void Save(string chanLstBinPath)
@@ -117,7 +124,9 @@ namespace ChanSort.Loader.Philips
{
var path = baseDir + entry.Key;
var data = File.ReadAllBytes(path);
- var length = Math.Min(data.Length, VersionMajor <= 12 ? 0x6000 : 0x145A00);
+ var length = data.Length;
+ if (VersionMajor < 12 && length > 0x6000)
+ length = 0x6000; // there might be another cap at 0x013FA000 + 0x6000 in some versions
var crc = Crc16.Calc(data, 0, length);
var off = entry.Value;
content[off] = (byte) crc;
diff --git a/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.csproj b/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.csproj
index 3684e8e..6dd8bb9 100644
--- a/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.csproj
+++ b/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.csproj
@@ -56,11 +56,13 @@
+
+ ..\DLL\System.Data.SQLite.dll
+
-
@@ -79,9 +81,9 @@
-
+
Always
-
+
\ No newline at end of file
diff --git a/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.ini b/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.ini
index 26977ef..3b8e074 100644
--- a/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.ini
+++ b/source/ChanSort.Loader.Philips/ChanSort.Loader.Philips.ini
@@ -47,7 +47,7 @@ offFreq=18
# ChannelMap_45 format
-[Map45_SatelliteDbBin_entry]
+[Map45_CableDb.bin_entry]
offId=0
offFreq=4
offProgNr=8
@@ -61,7 +61,26 @@ offScrambleStat=36
offLocked=40
offModulateion=44
offServiceType=52
+offServiceEdit=58
+offName=88
+lenName=64
+
+[Map45_SatelliteDb.bin_entry]
+offId=0
+offFreq=4
+offProgNr=8
+offAnalogUid=12
+offOnid=16
+offTsid=20
+offSid=24
+offSymbolRate=28
+offLogoNr=32
+offScrambleStat=36
+offLocked=40
+offModulateion=44
+offServiceType=52
+offServiceEdit=58
offName=80
lenName=64
offSatName=146
-lenSatName=64
\ No newline at end of file
+lenSatName=64
diff --git a/source/ChanSort.Loader.Philips/Channel.cs b/source/ChanSort.Loader.Philips/Channel.cs
index 70ef0b1..c2d9ac5 100644
--- a/source/ChanSort.Loader.Philips/Channel.cs
+++ b/source/ChanSort.Loader.Philips/Channel.cs
@@ -7,6 +7,7 @@ namespace ChanSort.Loader.Philips
{
public Channel(SignalSource source, long index, int oldProgNr, string name) : base(source, index, oldProgNr, name)
{
+ this.RecordOrder = (int)index;
}
internal Channel(SignalSource source, int order, int rowId, XmlNode setupNode)
@@ -27,6 +28,7 @@ namespace ChanSort.Loader.Philips
public string RawName;
public string RawSatellite;
public int Format;
+ public int Id; // links entries in the ChannelMap45/*Db.bin files with the entries in the tv.db channels table
}
}
diff --git a/source/ChanSort.Loader.Philips/PhilipsLoader.cs b/source/ChanSort.Loader.Philips/PhilipsLoader.cs
index 00e3fbd..2eecd01 100644
--- a/source/ChanSort.Loader.Philips/PhilipsLoader.cs
+++ b/source/ChanSort.Loader.Philips/PhilipsLoader.cs
@@ -29,7 +29,7 @@ namespace ChanSort.Loader.Philips
* e.g. 32PFL5806K/02, 42PFL7656K/02
*
* version 1.2
- * same as version 1.1
+ * same as version 1.1 for most parts, but different tuneinfo.dat format
* e.g. 32PFL5507K/12, 42PFL4317K/12, 32PFL5507K/12
*
* version 11.1
@@ -112,10 +112,10 @@ namespace ChanSort.Loader.Philips
if (majorVersion == 0 || majorVersion >= 100 && majorVersion <= 110)
return new XmlSerializer(inputFile);
- if (majorVersion == 1)
+ if (majorVersion == 1 || majorVersion == 45) // || majorVersion == 11 // format version 11 is similar to 1.x, but not (yet) supported
return new BinarySerializer(inputFile);
- throw new FileLoadException($"Selected file must be either chanLst.bin or CM_*.xml/.bin");
+ throw new FileLoadException($"Philips ChannelMap format version {majorVersion} is not supported.");
}
}
}
diff --git a/source/ChanSort.Loader.Philips/XmlSerializer.cs b/source/ChanSort.Loader.Philips/XmlSerializer.cs
index 18e00de..a77fd74 100644
--- a/source/ChanSort.Loader.Philips/XmlSerializer.cs
+++ b/source/ChanSort.Loader.Philips/XmlSerializer.cs
@@ -245,6 +245,12 @@ namespace ChanSort.Loader.Philips
medium = fname;
bool hasEncrypt = false;
+ foreach (var list in this.DataRoot.ChannelLists)
+ {
+ list.VisibleColumnFieldNames.Remove("ServiceType");
+ list.VisibleColumnFieldNames.Add("ServiceTypeName");
+ }
+
if (setupNode.HasAttribute("ChannelName"))
{
file.formatVersion = 1;
@@ -271,7 +277,6 @@ namespace ChanSort.Loader.Philips
list.VisibleColumnFieldNames.Remove("Favorites");
list.VisibleColumnFieldNames.Remove("Lock");
list.VisibleColumnFieldNames.Remove("Hidden");
- list.VisibleColumnFieldNames.Remove("ServiceType");
list.VisibleColumnFieldNames.Remove("ServiceTypeName");
list.VisibleColumnFieldNames.Remove("Encrypted");
}
@@ -354,11 +359,9 @@ namespace ChanSort.Loader.Philips
chan.TransportStreamId = ParseInt(data.TryGet("Tsid"));
chan.ServiceId = ParseInt(data.TryGet("Sid"));
chan.FreqInMhz = ParseInt(data.TryGet("Frequency")); ;
- if (chan.FreqInMhz > 2000)
+ if (chan.FreqInMhz > 2000 && (chan.SignalSource & SignalSource.Sat) == 0)
chan.FreqInMhz /= 1000;
- if (chan.FreqInMhz > 2000)
- chan.FreqInMhz /= 1000;
- chan.ServiceType = ParseInt(data.TryGet("ServiceType"));
+ chan.ServiceTypeName = ParseInt(data.TryGet("ServiceType")) == 1 ? "TV" : "Radio";
var decoderType = data.TryGet("DecoderType");
if (decoderType == "1")
chan.Source = "DVB-T";
@@ -366,6 +369,8 @@ namespace ChanSort.Loader.Philips
chan.Source = "DVB-C";
chan.SignalSource |= LookupData.Instance.IsRadioTvOrData(chan.ServiceType);
chan.SymbolRate = ParseInt(data.TryGet("SymbolRate"));
+ if (chan.SymbolRate > 100000) // DVB-S stores values in kSym, DVB-C stores it in Sym, DVB-T stores 0
+ chan.SymbolRate /= 1000;
if (data.TryGetValue("Polarization", out var pol))
chan.Polarity = pol == "0" ? 'H' : 'V';
chan.Hidden |= data.TryGet("SystemHidden") == "1";
@@ -382,9 +387,9 @@ namespace ChanSort.Loader.Philips
chan.Name = data.TryGet("name");
chan.RawName = chan.Name;
chan.FreqInMhz = ParseInt(data.TryGet("frequency"));
- //if ((chan.SignalSource & SignalSource.Analog) != 0)
+ //if ((chan.SignalSource & SignalSource.Analog) != 0) // analog channels have some really strange values (e.g. 00080 - 60512) that I can't convert to a plausible freq range (48-856 MHz)
// chan.FreqInMhz /= 16;
- if (chan.FreqInMhz > 1200)
+ if (chan.FreqInMhz > 1200 && (chan.SignalSource & SignalSource.Sat) == 0)
chan.FreqInMhz /= 1000;
chan.ServiceId = ParseInt(data.TryGet("serviceID"));
chan.OriginalNetworkId = ParseInt(data.TryGet("ONID"));
@@ -444,42 +449,12 @@ namespace ChanSort.Loader.Philips
foreach (var part in hexParts)
{
- if (part == "" || part == "0x00")
+ if (part == "")
continue;
buffer.WriteByte((byte)ParseInt(part));
}
- return this.DefaultEncoding.GetString(buffer.GetBuffer(), 0, (int)buffer.Length);
- }
- #endregion
-
- #region DefaultEncoding
- public override Encoding DefaultEncoding
- {
- get => base.DefaultEncoding;
- set
- {
- if (value == this.DefaultEncoding)
- return;
- base.DefaultEncoding = value;
- this.ChangeEncoding();
- }
- }
- #endregion
-
- #region ChangeEncoding
- private void ChangeEncoding()
- {
- foreach (var list in this.DataRoot.ChannelLists)
- {
- foreach (var channel in list.Channels)
- {
- if (!(channel is Channel ch))
- continue;
- ch.Name = this.DecodeName(ch.RawName);
- ch.Satellite = this.DecodeName(ch.RawSatellite);
- }
- }
+ return Encoding.Unicode.GetString(buffer.GetBuffer(), 0, (int) buffer.Length).TrimEnd('\x0');
}
#endregion
@@ -518,7 +493,7 @@ namespace ChanSort.Loader.Philips
{
// by default .NET reformats the whole XML. These settings produce almost same format as the TV xml files use
var xmlSettings = new XmlWriterSettings();
- xmlSettings.Encoding = this.DefaultEncoding;
+ xmlSettings.Encoding = new UTF8Encoding(false);
xmlSettings.CheckCharacters = false;
xmlSettings.Indent = true;
xmlSettings.IndentChars = " ";
@@ -616,10 +591,10 @@ namespace ChanSort.Loader.Philips
#region EncodeName
private string EncodeName(string name)
{
- var bytes = this.DefaultEncoding.GetBytes(name);
+ var bytes = Encoding.Unicode.GetBytes(name);
var sb = new StringBuilder();
foreach (var b in bytes)
- sb.Append($"0x{b:X2} 0x00 ");
+ sb.Append($"0x{b:X2} ");
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
diff --git a/source/ChanSort/ChanSort.csproj b/source/ChanSort/ChanSort.csproj
index d0b732c..0cb4ade 100644
--- a/source/ChanSort/ChanSort.csproj
+++ b/source/ChanSort/ChanSort.csproj
@@ -506,7 +506,7 @@
{68da8072-3a29-4076-9f64-d66f38349585}
ChanSort.Loader.Panasonic
-
+
{1f52b5ec-a2f1-4e53-9e1a-4658296c5bb5}
ChanSort.Loader.Philips
@@ -568,6 +568,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -592,9 +595,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
diff --git a/source/ChanSort/ReferenceLists/it_hotbird130E_FTA.txt b/source/ChanSort/ReferenceLists/it_hotbird130E_FTA.txt
deleted file mode 100644
index 959c63b..0000000
--- a/source/ChanSort/ReferenceLists/it_hotbird130E_FTA.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-1;Horse TV HD;200-1800-3629
-2;Radio Radio TV;318-15700-1329
-3;Yes TV;318-15700-1312
-4;Italian Fishing TV;318-9300-1602
-5;MS MOTORTV;318-9300-1613
-6;MS CHANNEL;318-9300-1614
-7;Well TV;318-900-503
-8;PACI CONTEMPORARY CHANNEL;318-9000-9014
-9;Wine TV;318-9300-1603
-10;Class TvModa;200-1800-3630
-11;RTL 102.5 NEWS;318-15700-1323
-12;RADIONORBA TV;318-15700-1311
-13;RDS Relax;318-15800-16978
-14;Canale Italia 83;318-13300-4961
-15;TRM h24;318-15800-16922
-16;TG NORBA 24;200-1800-3628
-17;Radio Cusano Campus;318-13300-4958
-18;Rete Uno;318-1700-14031
-19;Rete Due;318-1700-14032
-20;Rete Tre;318-1700-14033
-21;R-BuonConsiglio;200-1800-3636
-22;InBlu;64511-6700-11131
-23;INBLU2000;64511-6700-11174
-24;Radio Vaticana Europa;64511-6900-11181
-25;DimSuono Soft MI;318-7000-766
-26;DimSuono Soft RM;318-7000-767
-27;R. Eurospin;318-7000-749
-28;Radio PadrePio;318-7000-744
-29;Radio RADICALE;318-7000-761
-30;Radio Iglesias;318-7200-3654
-31;SMTv San Marino Radio;318-7200-7255
-32;Canale Italia 84;318-13300-4962
-33;Canale Italia;318-13300-4959
-34;Canale Italia 2;318-13300-4960
-35;TLC Telecampione;318-13300-4970
-36;Arte Investimenti;318-13300-4993
-37;Tesory Channel;318-900-532
-38;Arte Atelier;318-15800-16964
-39;Antichita Chiossone;318-15800-16965
-40;Deluxe 139;318-9000-9008
-41;TV Art Live;318-9300-1617
diff --git a/source/ChanSort/ReferenceLists/it_tivusat_EasyHD.txt b/source/ChanSort/ReferenceLists/it_tivusat_EasyHD.txt
deleted file mode 100644
index d836a70..0000000
--- a/source/ChanSort/ReferenceLists/it_tivusat_EasyHD.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-1;Rai 1 HD;318-5200-3401
-2;Rai 2 HD;318-5200-3402
-3;Rai 3 HD;318-5200-3403
-4;Rete4 HD;272-1200-123
-5;Canale5 HD;272-1200-122
-6;Italia1 HD;272-1200-121
-7;LA7 HD;272-6000-79
-8;TV8 HD;64511-6800-7260
-9;Nove HD;318-1000-4323
-10;Rai 4 HD;318-5200-3405
-11;Iris;272-1200-124
-12;La 5;272-1200-127
-13;Rai 5 HD;318-12500-17716
-14;Rai Movie HD;318-5200-3406
-15;Rai Premium HD;318-12500-17717
-16;Mediaset ITALIA DUE;272-1200-130
-17;Mediaset EXTRA;272-1200-129
-18;TV2000 HD;64511-6900-11180
-19;cielo HD;64511-6800-4120
-20;20 MEDIASET HD;272-1200-120
-21;Rai Sport + HD;318-5200-3404
-22;VH1;200-1800-3625
-23;Rai Storia HD;318-12500-17714
-24;Rai News 24 HD;318-12500-17711
-25;TgCom24;272-1200-128
-26;Spike;200-1800-3624
-27;Paramount Network HD;318-15700-1324
-28;DMAX HD;64511-6900-14253
-29;LA7d;272-6000-73
-31;Real Time HD;64511-6900-11507
-32;QVC HD;318-15800-16979
-33;Rai Scuola HD;318-12500-17715
-34;Cine34;272-1200-111
-35;Radio Italia Tv HD;318-15800-16962
-36;RTL 102.5 HD;318-15700-1307
-37;HSE24;318-12100-1731
-38;Giallo HD;318-1000-4322
-39;Topcrime;272-1200-132
-40;Boing;272-1200-126
-41;Cartoonito;272-1200-133
-42;Rai Gulp HD;318-12500-17712
-43;Rai YoYo HD;318-12500-17713
-44;-frisbee-;64511-6900-11418
-46;K2;64511-6900-11466
-47;Super!;200-1800-3621
-48;Arte HD;319-15900-307
-49;MEZZO;318-15600-10725
-50;RDS Social TV;318-15800-16977
-51;UNIRESAT HD;318-15800-16963
-53;Food Network HD;64511-6900-11722
-56;MotorTrend HD;318-1000-4321
-59;Euronews Italian;318-8900-2017
-60;Focus;272-1200-134
-61;BFC;318-15800-16980
-63;Radio Italia Trend TV HD;318-15800-16966
-64;Radio Kiss Kiss Tv;318-15800-16976
-65;RADIO ZETA HD;318-15700-1321
-66;RADIOFRECCIA HD;318-15700-1308
-67;RADIO MONTE CARLO;272-1200-119
-69;France 24 HD (in English);318-15300-808
-70;BBC World News;318-9400-8204
-71;Al Jazeera English HD;318-13100-7306
-72;TRT World HD;318-15300-803
-73;NHK WORLD-JAPAN;318-900-533
-75;France 24 HD (en Francais);318-15300-807
-77;Al Jazeera HD;318-9300-1601
-78;AlAraby TV HD;318-9000-9006
-79;Sonlife;318-700-9
-80;Juwelo TV;318-13300-4910
-81;CNBC HD;64511-6700-7245
-82;Bloomberg European TV;318-13100-7302
-83;i24News HD English;318-15700-1310
-84;i24News HD French;318-15700-1309
-85;DW English HD;318-5000-13101
-86;Euronews English HD;318-15300-801
-87;CGTN;318-15400-872
-88;CGTN Documentary;318-15400-873
-89;Senato;318-12400-8520
-90;Camera Deputati;318-12400-8519
-91;KBS World HD;318-15700-1313
-92;CCTV 4E;318-15400-871
-93;SMTv San Marino HD;318-7200-7254
-100;tivùlink;318-12400-8517
-101;Rai 1;318-12400-8511
-102;Rai 2;318-12400-8512
-103;Rai 3;318-12400-8513
-104;Rete 4;272-6000-3
-105;Canale 5;272-6000-2
-106;Italia 1;272-6000-1
-107;LA7;272-6000-71
-110;Rai 4;318-12400-8514
-111;Iris provvisorio;272-6000-4
-112;La 5 provvisorio;272-6000-7
-113;Rai 5;318-12400-8515
-114;Rai Movie;318-12400-8502
-115;Rai Premium;318-12400-8522
-116;Mediaset ITALIA DUE provvisorio;272-6000-10
-117;Mediaset EXTRA provvisorio;272-6000-9
-120;20 Mediaset provvisorio;272-6000-15
-121;Rai Sport;318-12400-8523
-123;Rai Storia;318-12400-8518
-124;Rai News 24;318-12400-8516
-125;TgCom24 provvisorio;272-6000-8
-127;Paramount Network;200-1800-3627
-132;QVC Italia;318-7000-780
-133;Rai Scuola;318-12400-8521
-139;Topcrime provvisorio;272-6000-12
-140;Boing provvisorio;272-6000-6
-141;Cartoonito provvisorio;272-6000-13
-142;Rai Gulp;318-12400-8524
-143;Rai YoYo;318-12400-8525
-160;Focus provvisorio;272-6000-14
-171;Al Jazeera English;318-13100-7305
-177;Al Jazeera;318-7000-708
-187;CGTN;318-12600-1706
-192;CCTV-4;318-7200-7224
-200;HotBird 4K1;318-700-17
-210;Rai 4K;318-5200-3407
-211;Nasa TV UHD;318-11100-4602
-220;Museum 4K;318-11100-4604
-222;MyZen 4K;318-9100-1104
-225;TRAVELXP 4K;318-11100-4603
-289;FTV UHD;318-9100-1102
-301;Rai 3 TGR Valle d'Aosta;318-12500-17744
-302;Rai 3 TGR Piemonte;318-12500-17739
-303;Rai 3 TGR Liguria;318-12500-17735
-304;Rai 3 TGR Lombardia;318-12500-17740
-305;Rai 3 TGR Veneto;318-12500-17742
-306;Rai 3 TGR Trentino Alto Adige Bolzano;318-12500-17752
-307;Rai 3 TGR Trentino Alto Adige Trento;318-12500-17751
-308;Rai 3 TGR Tagesschau;318-12500-17743
-309;Rai 3 TGR Friuli Venezia Giulia;318-12500-17749
-310;Rai 3 TGR Furlanija Julijska Krajina;318-12500-17750
-311;Rai 3 TGR Emilia-Romagna;318-12500-17741
-312;Rai 3 TGR Toscana;318-12500-17736
-313;Rai 3 TGR Marche;318-12500-17738
-314;Rai 3 TGR Umbria;318-12500-17737
-315;Rai 3 TGR Lazio;318-12500-17753
-316;Rai 3 TGR Abruzzo;318-12500-17746
-317;Rai 3 TGR Molise;318-12500-17747
-318;Rai 3 TGR Campania;318-12500-17748
-319;Rai 3 TGR Puglia;318-12500-17731
-320;Rai 3 TGR Basilicata;318-12500-17732
-321;Rai 3 TGR Calabria;318-12500-17733
-322;Rai 3 TGR Sardegna;318-12500-17745
-323;Rai 3 TGR Sicilia;318-12500-17734
-420;People TV;318-15700-1328
-422;Telecupole;318-13300-4994
-445;Padre Pio Tv;318-15800-16952
-454;Parole di Vita;318-900-510
-518;Emilia Romagna 24;318-15800-16920
-601;Rai Radio 1;318-5200-3441
-602;Rai Radio 2;318-5200-3442
-603;Rai Radio 3;318-5200-3443
-604;Rai GR Parlamento;318-5200-3445
-605;Rai Radio3 Classica;318-5200-3444
-606;Rai Radio Kids;318-5200-3449
-607;Rai Radio Live;318-5200-3448
-608;RDS;318-7000-736
-609;DimSuono Roma;318-7000-737
-610;RTL 102.5;318-7200-3642
-611;RADIO ZETA;318-7200-3643
-612;RADIO FRECCIA;318-7200-3630
-615;Radio 105;272-6000-105
-616;Virgin radio;272-6000-104
-617;Radio R101;272-6000-101
-618;Radio Monte Carlo;272-6000-102
-619;RMC2;272-6000-103
-620;RADIO ITALIA s.m.i.;318-7200-3632
-621;M DUE O;318-7200-3653
-622;CAPITAL;318-7200-3652
-623;DEEJAY;318-7200-3651
-624;Radio 24;318-7200-3644
-625;Discoradio;318-7000-768
-626;R.ONDA D'URTO;318-7200-3645
-627;ANNI 60;318-7000-738
-630;Rai Radio Tutta Italiana;318-5200-3451
-631;Radio Number One;318-15800-16981
-632;Radio Radio;318-7200-3646
-633;Radio Maria;318-7000-732
-634;RADIO MATER;318-7200-7280
-635;popolare;318-7200-3656
-637;Radio Margherita;318-13300-4957
-639;Rai Radio Slovenia;318-5200-3454
-640;Rai Radio Techete';318-5200-3447
-641;Rai Radio1 Sport;318-5200-3453
-642;Rai Radio2 Indie;318-5200-3450
-643;Radio Kiss Kiss;318-7000-742
-644;Radio Sportiva;318-7200-3637
-656;RFI Francais;318-5000-13130
-661;Swiss Pop;318-1700-14035
-662;Swiss Jazz;318-1700-14036
-663;Swiss Classica;318-1700-14047
-667;DW-FM02;318-5000-13124
-669;DW08;318-5000-13121
-670;DW09;318-5000-13122
-699;Rai Isoradio;318-5200-3446
-701;UNINETTUNO UNIVERSITY TV;318-12500-17718
-805;Mediaset Play;272-1200-805
-815;TELEPACE HD;318-8900-2004
-819;VIDEOLINA;318-15800-16992
-832;TVA Vicenza;318-15800-16988
-899;Infinity;272-1200-899
\ No newline at end of file
diff --git a/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_SatelliteDb-bin.h b/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_SatelliteDb-bin.h
index aa26e28..d49b4ba 100644
--- a/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_SatelliteDb-bin.h
+++ b/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_SatelliteDb-bin.h
@@ -3,6 +3,42 @@
/***********************************************************
* Philips ChannelMap_45 format
***********************************************************/
+
+public struct Ph_ChannelMap45_CableDbBin
+{
+ dword majorVersion;
+ dword minorVersion;
+ dword recordCount;
+ struct
+ {
+ var off0 = current_offset;
+ dword id;
+ dword freq;
+ dword number;
+ dword analogUid;
+ dword onid;
+ dword tsid;
+ dword sid;
+ dword symRate;
+ dword logoNr;
+ dword scrambleStat;
+ dword locked;
+ dword modulation;
+ dword unk1;
+ dword serviceType;
+ dword systemHideMaybe;
+ dword isUserModifiedLogo;
+ dword serviceEdit;
+ dword streamPriorityMaybe;
+ dword unk2;
+ word unk3TransponderRelated;
+ word unk4TransponderRelated;
+ byte unk3[8];
+ wchar_t name[32+1];
+
+ byte unk[156 - (current_offset - off0)];
+ } Channels[recordCount];
+};
public struct Ph_ChannelMap45_SatelliteDbBin
diff --git a/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_dat.h b/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_dat.h
index 1a8d638..763a45a 100644
--- a/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_dat.h
+++ b/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/philips_dat.h
@@ -45,7 +45,7 @@ public struct Ph_SatelliteDat
dword crc32;
};
-public struct Ph_TuneinfoDat
+public struct Ph_TuneinfoDat_1_0
{
word unk1;
word unk2;
@@ -66,7 +66,36 @@ public struct Ph_TuneinfoDat
byte unk2[9];
word tsid;
word onid;
- word unk3;
+ byte unk3[2];
+ char networkName[32];
+ word unk4;
+ byte unk[recordSize - (current_offset - off0)];
+ } Transponders[recordCount];
+ dword crc32;
+};
+
+public struct Ph_TuneinfoDat_1_2
+{
+ word unk1;
+ word unk2;
+ dword recordSize;
+ dword recordCount;
+ Ph_NextPrevTableEntry NextPrevTable[recordCount];
+ struct
+ {
+ var off0 = current_offset;
+ word symbolRate;
+ word freqInMhz;
+ word unk1;
+ struct
+ {
+ byte unk : 4;
+ byte satIndex: 4;
+ } u1a;
+ byte unk2[9];
+ word tsid;
+ word onid;
+ byte unk3[6];
char networkName[32];
word unk4;
byte unk[recordSize - (current_offset - off0)];
@@ -138,6 +167,37 @@ public struct Ph_FavoriteDat
dword crc32;
};
+public struct Ph_SatelliteDigSrvTable_11
+{
+ dword version;
+ dword unk2;
+ dword chRecordSize;
+ dword channelCount;
+ dword versionCode;
+ struct Ph_CableChannel
+ {
+ var off0 = current_offset;
+ dword checksum;
+ byte unk1[16];
+ dword symbolRate;
+ byte unk2[16];
+ dword freq;
+ word onid;
+ word sid;
+ word tsid;
+ byte unk3b[58];
+ word progNrMostly;
+ byte unk4[6];
+ word progNr;
+ byte unk5[22];
+ byte locked;
+ byte isFav;
+ byte unk6[68];
+ wchar_t channelName[32];
+ byte unk4[chRecordSize - (current_offset - off0)];
+ } Channels[channelCount];
+};
+
/***********************************************************
* channellib / antenna and cable files
***********************************************************/
diff --git a/source/changelog.md b/source/changelog.md
index 5ff8e75..df2e7bf 100644
--- a/source/changelog.md
+++ b/source/changelog.md
@@ -1,6 +1,12 @@
ChanSort Change Log
===================
+2021-01-17
+- Philips: added support for ChannelMap_45 format
+- Philips: fixed display of symbol rate and frequency (off by factor 1000 depending of list and DVB source)
+- Philips: fixed special characters in channel names (e.g. german umlauts)
+- Philips: "ServiceType" now only shows "TV" or "Radio". There is no information about HD/SD in the file.
+
2021-01-02
- Grundig: added support for dvb*_config.xml channel lists