using System; using System.Collections.Generic; using System.Text; using ChanSort.Api; namespace ChanSort.Loader.Samsung { public class ScmChannelBase : ChannelInfo { // common private const string _InUse = "InUse"; private const string _ProgramNr = "offProgramNr"; private const string _Name = "offName"; private const string _NameLength = "offNameLength"; private const string _ShortName = "offShortName"; private const string _Favorites = "offFavorites"; private const string _IsActive = "IsActive"; private const string _Deleted = "Deleted"; private const string _Encrypted = "Encrypted"; private const string _Lock = "Lock"; private const string _Checksum = "offChecksum"; // DVB private const string _ServiceId = "offServiceId"; private const string _VideoPid = "offVideoPid"; private const string _AudioPid = "offAudioPid"; private const string _OriginalNetworkId = "offOriginalNetworkId"; private const string _TransportStreamId = "offTransportStreamId"; private const string _ServiceType = "offServiceType"; private const string _SymbolRate = "offSymbolRate"; private const string _ServiceProviderId = "offServiceProviderId"; private static readonly Encoding Utf16BigEndian = new UnicodeEncoding(true, false); private readonly FavoritesIndexMode sortedFavorites; protected readonly DataMapping mapping; protected readonly byte[] rawData; internal readonly int baseOffset; internal bool InUse { get; set; } protected ScmChannelBase(DataMapping data, FavoritesIndexMode sortedFavorites) { this.mapping = data; this.rawData = data.Data; this.baseOffset = data.BaseOffset; this.mapping.DefaultEncoding = Utf16BigEndian; this.sortedFavorites = sortedFavorites; } #region InitCommonData() protected void InitCommonData(int slot, SignalSource signalSource, DataMapping data) { this.InUse = data.GetFlag(_InUse, true); this.RecordIndex = slot; this.RecordOrder = slot; this.SignalSource = signalSource; this.OldProgramNr = (short)data.GetWord(_ProgramNr); this.Name = data.GetString(_Name, data.Settings.GetInt("lenName")); this.Favorites = this.ParseRawFavorites(); this.Lock = data.GetFlag(_Lock); this.Encrypted = data.GetFlag(_Encrypted); this.IsDeleted = data.GetFlag(_Deleted, false) || !data.GetFlag(_IsActive, true); if (this.IsDeleted) this.OldProgramNr = -1; } #endregion #region ParseRawFavorites() private Favorites ParseRawFavorites() { var offsets = mapping.GetOffsets(_Favorites); if (offsets.Length == 1) // series B,C return (Favorites) mapping.GetByte(_Favorites); // series D,E,F byte fav = 0; byte mask = 0x01; int favIndex = 0; foreach (int off in offsets) { int favValue = BitConverter.ToInt32(this.rawData, baseOffset + off); if (sortedFavorites == FavoritesIndexMode.Boolean && favValue != 0) fav |= mask; else if (sortedFavorites != FavoritesIndexMode.Boolean && favValue != -1) fav |= mask; if (sortedFavorites == FavoritesIndexMode.IndividuallySorted) this.FavIndex[favIndex] = favValue; mask <<= 1; ++favIndex; } return (Favorites) fav; } #endregion #region InitDvbData() protected void InitDvbData(DataMapping data, IDictionary providerNames) { this.ShortName = data.GetString(_ShortName, data.Settings.GetInt("lenShortName")); this.ServiceId = data.GetWord(_ServiceId); //this.PcrPid = data.GetWord(_PcrPid); this.VideoPid = data.GetWord(_VideoPid); this.AudioPid = data.GetWord(_AudioPid); this.OriginalNetworkId = data.GetWord(_OriginalNetworkId); this.TransportStreamId = data.GetWord(_TransportStreamId); this.ServiceType = data.GetByte(_ServiceType); this.SymbolRate = data.GetWord(_SymbolRate); if (data.Settings.GetInt(_ServiceProviderId, -1) != -1) { int source = -1; if ((this.SignalSource & SignalSource.MaskProvider) == SignalSource.Freesat) source = 4; else if ((this.SignalSource & SignalSource.MaskProvider) == SignalSource.TivuSat) source = 6; else if ((this.SignalSource & SignalSource.Antenna) != 0) source = 0; else if ((this.SignalSource & SignalSource.Cable) != 0) source = 1; else if ((this.SignalSource & SignalSource.Sat) != 0) source = 3; int providerId = data.GetWord(_ServiceProviderId); this.Provider = providerNames.TryGet((source << 16) + providerId); } this.SignalSource |= LookupData.Instance.IsRadioOrTv(this.ServiceType); } #endregion #region UpdateRawData() public override void UpdateRawData() { mapping.SetDataPtr(this.rawData, this.baseOffset); mapping.SetFlag(_InUse, this.InUse); if (this.NewProgramNr >= 0) mapping.SetWord(_ProgramNr, this.NewProgramNr); if (this.IsNameModified) { int bytes = mapping.SetString(_Name, this.Name, mapping.Settings.GetInt("lenName")); mapping.SetByte(_NameLength, bytes); this.IsNameModified = false; } this.UpdateRawFavorites(); mapping.SetFlag(_Lock, this.Lock); mapping.SetFlag(_Deleted, this.NewProgramNr < 0); mapping.SetFlag(_IsActive, this.NewProgramNr >= 0); this.UpdateChecksum(); } #endregion #region EraseRawData() internal virtual void EraseRawData() { int len = this.mapping.Settings.GetInt("offChecksum") + 1; Tools.MemSet(this.rawData, this.baseOffset, 0, len); } #endregion #region UpdateRawFavorites() private void UpdateRawFavorites() { var offsets = mapping.GetOffsets(_Favorites); if (offsets.Length == 1) // series B,C { mapping.SetByte(_Favorites, (byte)this.Favorites & 0x0F); return; } // series D,E,F byte fav = (byte)this.Favorites; byte mask = 0x01; int favIndex = 0; foreach (int off in offsets) { int favValue; if (this.sortedFavorites == FavoritesIndexMode.Boolean) // D series favValue = (fav & mask) != 0 ? 1 : 0; // D series else if (this.sortedFavorites == FavoritesIndexMode.IndividuallySorted) // E series (and some F models with early firmware) favValue = (fav & mask) != 0 ? this.FavIndex[favIndex] : -1; else favValue = (fav & mask) != 0 ? this.NewProgramNr : -1; // F series (newer models/firmware), H series Array.Copy(BitConverter.GetBytes(favValue), 0, this.rawData, baseOffset + off, 4); mask <<= 1; ++favIndex; } } #endregion #region UpdateChecksum() private void UpdateChecksum() { var offChecksum = this.baseOffset + this.mapping.GetOffsets(_Checksum)[0]; byte crc = 0; for (int i = this.baseOffset; i < offChecksum; i++) crc += this.rawData[i]; this.rawData[offChecksum] = crc; } #endregion } }