summaryrefslogtreecommitdiff
path: root/eepg.c
diff options
context:
space:
mode:
authorDimitar Petrovski <dimeptr@gmail.com>2012-11-30 12:53:29 (GMT)
committerDimitar Petrovski <dimeptr@gmail.com>2012-11-30 12:53:29 (GMT)
commitc0c90a946c0f5a6722f312e7156ba01c9e743d56 (patch)
treedc984296d4eda579f9632ee032bf1a62266bcc40 /eepg.c
parent16676f55d7aabc55a7b2894dbdf79a462749767f (diff)
parent250c584c8b52ca6fadc75acc1f8f9e6c2830c014 (diff)
downloadvdr-plugin-eepg-c0c90a946c0f5a6722f312e7156ba01c9e743d56.tar.gz
vdr-plugin-eepg-c0c90a946c0f5a6722f312e7156ba01c9e743d56.tar.bz2
Merge branch 'experimental'
Conflicts: eepg.c
Diffstat (limited to 'eepg.c')
-rw-r--r--eepg.c1638
1 files changed, 390 insertions, 1248 deletions
diff --git a/eepg.c b/eepg.c
index e469313..cced41b 100644
--- a/eepg.c
+++ b/eepg.c
@@ -38,14 +38,19 @@
#include <libsi/si.h>
#include "eepg.h"
#include "dish.h"
+#if APIVERSNUM > 10725
+#include "epghandler.h"
+#endif
+#include "log.h"
+#include "setupeepg.h"
+#include "equivhandler.h"
+#include "util.h"
+#include "eit2.h"
#include <map>
#include <string>
#include <stdarg.h>
-#define VERBOSE 1
-/* 0 = only print errors, 1 = print channels and themes, 2 = print channels, themes, titles, summaries 3 = debug mode */
-/* all is logged into /var/log/syslog */
#if APIVERSNUM < 10401
#error You need at least VDR API version 1.4.1 for this plugin
@@ -54,37 +59,14 @@
#define trNOOP(s) (s)
#endif
-//#define DEBUG
-//#define DEBUG2
-
-/*#ifdef DEBUG
-#define d(x) { (x); }
-#else
-#define d(x) ;
-#endif
-#ifdef DEBUG2
-#define d2(x) { (x); }
-#else
-#define d2(x) ;
-#endif*/
-
#define PMT_SCAN_TIMEOUT 10 // seconds
#define PMT_SCAN_IDLE 3600 // seconds
static const char *VERSION = "0.0.6pre";
static const char *DESCRIPTION = trNOOP ("Parses Extended EPG data");
-template <class T> T REALLOC(T Var, size_t Size)
-{
- T p = (T)realloc(Var, Size);
- if (!p)
- free(Var);
- return p;
-}
-
using namespace std;
-
-// --- cSetupEEPG -------------------------------------------------------
+using namespace util;
const char *optPats[] = {
"%s",
@@ -110,43 +92,14 @@ char *cs_hexdump (int m, const uchar * buf, int n)
return (dump);
}
-class cSetupEEPG
-{
-public:
- int OptPat;
- int OrderInfo;
- int RatingInfo;
- int FixEpg;
- int DisplayMessage;
-#ifdef DEBUG
- int LogLevel;
-#endif
-
-public:
- cSetupEEPG (void);
-};
-
-cSetupEEPG SetupPE;
-
-cSetupEEPG::cSetupEEPG (void)
-{
- OptPat = 1;
- OrderInfo = 1;
- RatingInfo = 1;
- FixEpg = 0;
- DisplayMessage = 1;
-#ifdef DEBUG
- LogLevel = 0;
-#endif
-
-}
+cSetupEEPG* SetupPE = cSetupEEPG::getInstance();
// --- cMenuSetupPremiereEpg ------------------------------------------------------------
class cMenuSetupPremiereEpg:public cMenuSetupPage
{
private:
- cSetupEEPG data;
+ cSetupEEPG* data;
const char *optDisp[NUM_PATS];
char buff[NUM_PATS][32];
protected:
@@ -157,93 +110,39 @@ public:
cMenuSetupPremiereEpg::cMenuSetupPremiereEpg (void)
{
- data = SetupPE;
+ data = cSetupEEPG::getInstance();
SetSection (tr ("PremiereEPG"));
optDisp[0] = tr ("off");
for (unsigned int i = 1; i < NUM_PATS; i++) {
snprintf (buff[i], sizeof (buff[i]), optPats[i], "Event", 1);
optDisp[i] = buff[i];
}
- Add (new cMenuEditStraItem (tr ("Tag option events"), &data.OptPat, NUM_PATS, optDisp));
- Add (new cMenuEditBoolItem (tr ("Show order information"), &data.OrderInfo));
- Add (new cMenuEditBoolItem (tr ("Show rating information"), &data.RatingInfo));
- Add (new cMenuEditBoolItem (tr ("Fix EPG data"), &data.FixEpg));
- Add (new cMenuEditBoolItem (tr ("Display summary message"), &data.DisplayMessage));
+ Add (new cMenuEditStraItem (tr ("Tag option events"), &data->OptPat, NUM_PATS, optDisp));
+ Add (new cMenuEditBoolItem (tr ("Show order information"), &data->OrderInfo));
+ Add (new cMenuEditBoolItem (tr ("Show rating information"), &data->RatingInfo));
+ Add (new cMenuEditBoolItem (tr ("Fix EPG data"), &data->FixEpg));
+ Add (new cMenuEditBoolItem (tr ("Display summary message"), &data->DisplayMessage));
#ifdef DEBUG
- Add (new cMenuEditIntItem (tr ("Level of logging verbosity"), &data.LogLevel, 0, 5));
+ Add (new cMenuEditIntItem (tr ("Level of logging verbosity"), &data->LogLevel, 0, 5));
+ Add (new cMenuEditBoolItem (tr ("Process EIT info with EEPG"), &data->ProcessEIT));
#endif
}
void cMenuSetupPremiereEpg::Store (void)
{
- SetupPE = data;
- SetupStore ("OptionPattern", SetupPE.OptPat);
- SetupStore ("OrderInfo", SetupPE.OrderInfo);
- SetupStore ("RatingInfo", SetupPE.RatingInfo);
- SetupStore ("FixEpg", SetupPE.FixEpg);
- SetupStore ("DisplayMessage", SetupPE.DisplayMessage);
-#ifdef DEBUG
- SetupStore ("LogLevel", SetupPE.LogLevel);
-#endif
-}
-
-bool CheckLevel(int level)
-{
+ //SetupPE = data;
+ SetupStore ("OptionPattern", SetupPE->OptPat);
+ SetupStore ("OrderInfo", SetupPE->OrderInfo);
+ SetupStore ("RatingInfo", SetupPE->RatingInfo);
+ SetupStore ("FixEpg", SetupPE->FixEpg);
+ SetupStore ("DisplayMessage", SetupPE->DisplayMessage);
#ifdef DEBUG
- if (SetupPE.LogLevel >= level)
-#else
- if (VERBOSE >= level)
+ SetupStore ("LogLevel", SetupPE->LogLevel);
+ SetupStore ("ProcessEIT", SetupPE->ProcessEIT);
#endif
- {
- return true;
- }
- return false;
-}
-
-const char* PrepareLog(string message)
-{
- message = "EEPG: " + message;
- return message.c_str();
}
-#define MAXSYSLOGBUF 256
-
-//void LogVsyslog(int errLevel, const char * message, ...)
-void LogVsyslog(int errLevel, int const& lineNum, const char * function, const char * message, ...)
-{
- va_list ap;
- char fmt[MAXSYSLOGBUF];
- if (errLevel == LOG_DEBUG) {
- snprintf(fmt, sizeof(fmt), "[%d] %s:%d %s", cThread::ThreadId(), function, lineNum, message);
- } else {
- snprintf(fmt, sizeof(fmt), "[%d] %s", cThread::ThreadId(), message);
- }
- va_start(ap,message);
- vsyslog ( errLevel, fmt, ap );
- va_end(ap);
-}
-
-#define LogI(a, b...) void( CheckLevel(a) ? LogVsyslog ( LOG_INFO, __LINE__, __FUNCTION__, b ) : void() )
-#define LogE(a, b...) void( CheckLevel(a) ? LogVsyslog ( LOG_ERR, __LINE__, __FUNCTION__, b ) : void() )
-#define LogD(a, b...) void( CheckLevel(a) ? LogVsyslog ( LOG_DEBUG, __LINE__, __FUNCTION__, b ) : void() )
-//#define LogE(a, b...) void( CheckLevel(a) ? esyslog ( b ) : void() )
-//#define LogD(a, b...) void( CheckLevel(a) ? dsyslog ( b ) : void() )
-#define prep(s) PrepareLog(s)
-#define prep2(s) s
-
-//void LogF(int level, const char * message, ...) __attribute__ ((format (printf,2,3)));
-
-//void LogF(int level, const char * message, ...)
-//{
-// if (CheckLevel(level)) {
-// va_list ap;
-// va_start(ap,message);
-// vsyslog (LOG_ERR, PrepareLog(message), ap );
-// va_end(ap);
-// }
-//}
-
-#define Asprintf(a, b, c...) void( asprintf(a, b, c) < 0 ? esyslog("memory allocation error - %s", b) : void() )
+//#define Asprintf(a, b, c...) void( asprintf(a, b, c) < 0 ? esyslog("memory allocation error - %s", b) : void() )
// --- CRC16 -------------------------------------------------------------------
@@ -263,36 +162,15 @@ unsigned int crc16 (unsigned int crc, unsigned char const *p, int len)
#define STARTTIME_BIAS (20*60)
-static int AvailableSources[32];
-static int NumberOfAvailableSources = 0;
static int LastVersionNagra = -1; //currently only used for Nagra, should be stored per transponder, per system
-#ifdef USE_NOEPG
-bool allowedEPG (tChannelID kanalID)
-{
- bool rc;
-
- if (Setup.noEPGMode == 1) {
- rc = false;
- if (strstr (::Setup.noEPGList, kanalID.ToString ()) != NULL)
- rc = true;
- } else {
- rc = true;
- if (strstr (::Setup.noEPGList, kanalID.ToString ()) != NULL)
- rc = false;
- }
-
- return rc;
-}
-#endif /* NOEPG */
-
class cFilterEEPG:public cFilter
{
private:
int pmtpid, pmtsid, pmtidx, pmtnext;
int UnprocessedFormat[HIGHEST_FORMAT + 1]; //stores the pid when a format is detected on this transponder, and that are not processed yet
- int nEquivChannels, nChannels, nThemes, nTitles, nSummaries, NumberOfTables, Version;
+ int nChannels, nThemes, nTitles, nSummaries, NumberOfTables, Version;
int TitleCounter, SummaryCounter, NoSummaryCounter, RejectTableId;
bool EndChannels, EndThemes; //only used for ??
int MHWStartTime; //only used for MHW1
@@ -315,7 +193,7 @@ private:
unsigned char InitialSummary[64];
void NextPmt (void);
- void ProccessContinuous(u_short Pid, u_char Tid, int Length, const u_char *Data);
+ void ProccessContinuous(u_short Pid, u_char Tid, int Length, const u_char *Data);
protected:
virtual void Process (u_short Pid, u_char Tid, const u_char * Data, int Length);
virtual void AddFilter (u_short Pid, u_char Tid);
@@ -340,14 +218,13 @@ protected:
virtual int GetSummariesMHW2 (const u_char * Data, int Length);
virtual void FreeSummaries (void);
virtual void FreeTitles (void);
- virtual void PrepareToWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES]); //gets a channel and returns an array of schedules that WriteToSchedule can write to. Call this routine before a batch of titles with the same ChannelId will be WriteToScheduled; batchsize can be 1
- virtual void FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES]);
- virtual void WriteToSchedule (cSchedule * ps[MAX_EQUIVALENCES], unsigned short int NumberOfEquivalences,
- unsigned int EventId, unsigned int StartTime, unsigned int Duration, char *Text,
- char *SummText, unsigned short int ThemeId, unsigned short int TableId,
- unsigned short int Version, char Rating = 0x00);
+ //virtual void PrepareToWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps/*[MAX_EQUIVALENCES]*/); //gets a channel and returns an array of schedules that WriteToSchedule can write to. Call this routine before a batch of titles with the same ChannelId will be WriteToScheduled; batchsize can be 1
+ //virtual void FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES]);
+ virtual void WriteToSchedule (tChannelID channelID, cSchedules* s, unsigned int EventId, unsigned int StartTime,
+ unsigned int Duration, char *Text, char *SummText, unsigned short int ThemeId,
+ unsigned short int TableId, unsigned short int Version, char Rating = 0x00);
virtual void LoadIntoSchedule (void);
- virtual void LoadEquivalentChannels (void);
+ //virtual void LoadEquivalentChannels (void);
void ProcessPremiere(const u_char *& Data);
public:
@@ -355,10 +232,14 @@ public:
virtual void SetStatus (bool On);
void Trigger (void);
bool InitDictionary (void); //Initialize the Huffman tables for SKY and Freesat
+
+ static const int EIT_PID = 0x12;
};
cFilterEEPG::cFilterEEPG (void)
{
+ nSummaries = 0;
+ nTitles = 0;
Trigger ();
//Set (0x00, 0x00);
}
@@ -425,21 +306,21 @@ void syslog_with_tid (int priority, const char *format, ...) __attribute__ ((for
-struct hufftab {
- unsigned int value;
- short bits;
- char next;
-};
+//struct hufftab {
+// unsigned int value;
+// short bits;
+// char next;
+//};
+//
+//#define START '\0'
+//#define STOP '\0'
+//#define ESCAPE '\1'
-#define START '\0'
-#define STOP '\0'
-#define ESCAPE '\1'
+//int freesat_decode_error = 0; /* If set an error has occurred during decoding */
-int freesat_decode_error = 0; /* If set an error has occurred during decoding */
-
-static struct hufftab *tables[2][256];
-static int table_size[2][256];
+//static struct hufftab *tables[2][128];
+//static int table_size[2][128];
static sNodeH* sky_tables[2];
/** \brief Convert a textual character description into a value
@@ -520,6 +401,9 @@ static bool load_freesat_file (int tableid, const char *filename)
tables[tableid][from_char][i].value = bin;
tables[tableid][from_char][i].next = to_char;
tables[tableid][from_char][i].bits = bin_len;
+ /* char from; unsigned int value; short bits; char next; */
+ LogI(2, prep("%02x;%08x;%04x;%02x"), from_char, bin, bin_len, to_char);
+
free (from);
free (to);
free (binary);
@@ -570,7 +454,7 @@ static bool load_sky_file (const char *filename)
memset (string1, 0, sizeof (string1));
memset (string2, 0, sizeof (string2));
if (sscanf (Line, "%c=%[^\n]\n", string1, string2) == 2
- || (sscanf (Line, "%[^=]=%[^\n]\n", string1, string2) == 2)) {
+ || (sscanf (Line, "%[^=]=%[^\n]\n", string1, string2) == 2)) {
nH = sky_tables[tableId];
LenPrefix = strlen (string2);
for (i = 0; i < LenPrefix; i++) {
@@ -589,7 +473,7 @@ static bool load_sky_file (const char *filename)
nH = nH->P0;
if (nH->Value != NULL || (LenPrefix - 1) == i) {
LogE (0 ,prep("Error, huffman prefix code already exists for \"%s\"=%s with '%s'"), string1,
- string2, nH->Value);
+ string2, nH->Value);
}
}
break;
@@ -607,7 +491,7 @@ static bool load_sky_file (const char *filename)
nH = nH->P1;
if (nH->Value != NULL || (LenPrefix - 1) == i) {
LogE (0, prep("Error, huffman prefix code already exists for \"%s\"=%s with '%s'"), string1,
- string2, nH->Value);
+ string2, nH->Value);
}
}
break;
@@ -633,7 +517,7 @@ static bool load_sky_file (const char *filename)
memset (string1, 0, sizeof (string1));
memset (string2, 0, sizeof (string2));
if (sscanf (Line, "%c=%[^\n]\n", string1, string2) == 2
- || (sscanf (Line, "%[^=]=%[^\n]\n", string1, string2) == 2)) {
+ || (sscanf (Line, "%[^=]=%[^\n]\n", string1, string2) == 2)) {
nH = sky_tables[tableId];
LenPrefix = strlen (string2);
for (i = 0; i < LenPrefix; i++) {
@@ -678,7 +562,7 @@ static bool load_sky_file (const char *filename)
char *freesat_huffman_decode (const unsigned char *src, size_t size)
{
int tableid;
- freesat_decode_error = 0;
+// freesat_decode_error = 0;
if (src[0] == 0x1f && (src[1] == 1 || src[1] == 2)) {
int uncompressed_len = 30;
@@ -857,120 +741,13 @@ nextloop1:
//here all declarations for global variables over all devices
-char *ConfDir;
+//char *ConfDir;
//unsigned char DecodeErrorText[4096]; //TODO only used for debugging?
-int Yesterday;
-int YesterdayEpoch;
-int YesterdayEpochUTC;
-
-/*
- * Convert local time to UTC
- */
-time_t LocalTime2UTC (time_t t)
-{
- struct tm *temp;
-
- temp = gmtime (&t);
- temp->tm_isdst = -1;
- return mktime (temp);
-}
-
-/*
- * Convert UTC to local time
- */
-time_t UTC2LocalTime (time_t t)
-{
- return 2 * t - LocalTime2UTC (t);
-}
-
-void GetLocalTimeOffset (void)
-{
- time_t timeLocal;
- struct tm *tmCurrent;
-
- timeLocal = time (NULL);
- timeLocal -= 86400;
- tmCurrent = gmtime (&timeLocal);
- Yesterday = tmCurrent->tm_wday;
- tmCurrent->tm_hour = 0;
- tmCurrent->tm_min = 0;
- tmCurrent->tm_sec = 0;
- tmCurrent->tm_isdst = -1;
- YesterdayEpoch = mktime (tmCurrent);
- YesterdayEpochUTC = UTC2LocalTime (mktime (tmCurrent));
-}
-
-void CleanString (unsigned char *String)
-{
-
-// LogD (1, prep("Unclean: %s"), String);
- unsigned char *Src;
- unsigned char *Dst;
- int Spaces;
- int pC;
- Src = String;
- Dst = String;
- Spaces = 0;
- pC = 0;
- while (*Src) {
- // corrections
- if (*Src == 0x8c) { // iso-8859-2 LATIN CAPITAL LETTER S WITH ACUTE
- *Src = 0xa6;
- }
- if (*Src == 0x8f) { // iso-8859-2 LATIN CAPITAL LETTER Z WITH ACUTE
- *Src = 0xac;
- }
-
- if (*Src!=0x0A && *Src < 0x20) { //don't remove newline
- *Src = 0x20;
- }
- if (*Src == 0x20) {
- Spaces++;
- if (pC == 0) {
- Spaces++;
- }
- } else {
- Spaces = 0;
- }
- if (Spaces < 2) {
- *Dst = *Src;
- Dst++;
- pC++;
- }
- Src++;
- }
- if (Spaces > 0) {
- Dst--;
- *Dst = 0;
- } else {
- *Dst = 0;
- }
-// LogD (1, prep("Clean: %s"), String);
-}
-
-cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos)
-{
- cChannel *VC = Channels.GetByChannelID(channelID, true);
- if(!VC && searchOtherPos){
- //look on other satpositions
- for(int i = 0;i < NumberOfAvailableSources;i++){
- channelID = tChannelID(AvailableSources[i], channelID.Nid(), channelID.Tid(), channelID.Sid());
- VC = Channels.GetByChannelID(channelID, true);
- if(VC){
- //found this actually on satellite nextdoor...
- break;
- }
- }
- }
-
- return VC;
-}
-
bool cFilterEEPG::GetThemesSKYBOX (void) //TODO can't we read this from the DVB stream?
{
- string FileName = ConfDir;
+ string FileName = cSetupEEPG::getInstance()->getConfDir();
FILE *FileThemes;
char *Line;
char Buffer[256];
@@ -1018,7 +795,7 @@ bool cFilterEEPG::GetThemesSKYBOX (void) //TODO can't we read this from the DVB
*/
bool cFilterEEPG::InitDictionary (void)
{
- string FileName = ConfDir;
+ string FileName = cSetupEEPG::getInstance()->getConfDir();
switch (Format) {
case SKY_IT:
if (sky_tables[0] == NULL) {
@@ -1041,8 +818,8 @@ bool cFilterEEPG::InitDictionary (void)
LogD (4, prep("EEPGDebug: loading freesat.dict"));
FileName += "/freesat.t1";
if (!load_freesat_file (1, FileName.c_str()))
- return false;
- FileName = ConfDir;
+ return false;
+ FileName = cSetupEEPG::getInstance()->getConfDir();
FileName += "/freesat.t2";
return load_freesat_file (2, FileName.c_str());
} else
@@ -1055,125 +832,6 @@ bool cFilterEEPG::InitDictionary (void)
return true;
}
-void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize)
-{
- if (from[0] == 0x1f) {
- char *temp = freesat_huffman_decode (from, len);
- if (temp) {
- len = strlen (temp);
- len = len < buffsize - 1 ? len : buffsize - 1;
- strncpy (buffer, temp, len);
- buffer[len] = 0;
- free (temp);
- return;
- }
- }
-
- if (from[0] == 0x1f) {
- char *temp = freesat_huffman_decode (from, len);
- if (temp) {
- len = strlen (temp);
- len = len < buffsize - 1 ? len : buffsize - 1;
- strncpy (buffer, temp, len);
- buffer[len] = 0;
- free (temp);
- return;
- }
- }
-
- SI::String convStr;
- SI::CharArray charArray;
- charArray.assign(from, len);
- convStr.setData(charArray, len);
- //LogE(5, prep("decodeText2 from %s - length %d"), from, len);
- convStr.getText(buffer, buffsize);
- //LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize);
-}
-
-void cFilterEEPG::LoadEquivalentChannels (void)
-{
- char Buffer[1024];
- char *Line;
- FILE *File;
- string FileName = string(ConfDir) + "/" + EEPG_FILE_EQUIV;
-
- File = fopen (FileName.c_str(), "r");
- if (File) {
- memset (Buffer, 0, sizeof (Buffer));
- char string1[256];
- char string2[256];
- char string3[256];
- int int1;
- int int2;
- int int3;
- int int4;
- while ((Line = fgets (Buffer, sizeof (Buffer), File)) != NULL) {
- Line = compactspace (skipspace (stripspace (Line)));
- if (!isempty (Line)) {
- if (sscanf (Line, "%[^ ] %[^ ] %[^\n]\n", string1, string2, string3) == 3) {
- if (string1[0] != '#' && string1[0] != ';') {
- int1 = 0; //TODO: this could be made more readable
- int2 = 0;
- int3 = 0;
- int4 = 0;
- if (sscanf (string1, "%[^-]-%i -%i -%i ", string3, &int1, &int2, &int3) == 4)
- if (sscanf (string2, "%[^-]-%i -%i -%i ", string3, &int1, &int2, &int3) == 4) {
- if (sscanf (string1, "%[^-]-%i -%i -%i -%i ", string3, &int1, &int2, &int3, &int4) != 5) {
- int4 = 0;
- }
- tChannelID OriginalChID = tChannelID (cSource::FromString (string3), int1, int2, int3, int4);
- bool found = false;
- int i = 0;
- sChannel *C = NULL;
- while (i < nChannels && (!found)) {
- C = &sChannels[i];
- if (C->Src[0] == (unsigned int)cSource::FromString (string3) && C->Nid[0] == int1
- && C->Tid[0] == int2 && C->Sid[0] == int3)
- found = true;
- else
- i++;
- }
- if (!found) {
- LogI(2, prep("Warning: in equivalence file, cannot find original channel %s. Perhaps you are tuned to another transponder right now."),
- string1);
- } else {
- cChannel *OriginalChannel = Channels.GetByChannelID (OriginalChID, false);
- if (!OriginalChannel)
- LogI(2, prep("Warning, not found epg channel \'%s\' in channels.conf. Equivalency is assumed to be valid, but perhaps you should check the entry in the equivalents file"), string1); //TODO: skip this ing?
- if (sscanf (string2, "%[^-]-%i -%i -%i ", string3, &int1, &int2, &int3) == 4) {
- if (sscanf (string2, "%[^-]-%i -%i -%i -%i ", string3, &int1, &int2, &int3, &int4)
- != 5) {
- int4 = 0;
- }
- tChannelID EquivChID = tChannelID (cSource::FromString (string3), int1, int2, int3, int4);
- cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); //TODO use valid function?
- if (EquivChannel) {
- if (C->NumberOfEquivalences < MAX_EQUIVALENCES) {
- C->Src[C->NumberOfEquivalences] = EquivChannel->Source ();
- C->Nid[C->NumberOfEquivalences] = EquivChannel->Nid ();
- C->Tid[C->NumberOfEquivalences] = EquivChannel->Tid ();
- C->Sid[C->NumberOfEquivalences] = EquivChannel->Sid ();
- C->NumberOfEquivalences++;
- nEquivChannels++;
- LogI(3, prep("Added equivalent nr %i with Channel Id %s-%i-%i-%i to channel with id %i."),
- C->NumberOfEquivalences, *cSource::ToString (C->Src[C->NumberOfEquivalences - 1]),
- C->Nid[C->NumberOfEquivalences - 1], C->Tid[C->NumberOfEquivalences - 1],
- C->Sid[C->NumberOfEquivalences - 1], i);
- } else
- LogE(0, prep("Error, channel with id %i has more than %i equivalences. Increase MAX_EQUIVALENCES."),
- i, MAX_EQUIVALENCES);
- } else
- LogI(0, prep("Warning, not found equivalent channel \'%s\' in channels.conf"), string2);
- }
- } //else !found
- } //if scanf string1
- } //if string1
- } //if scanf
- } //if isempty
- } //while
- fclose (File);
- } //if file
-} //end of loadequiv
/**
* \brief Get MHW channels
@@ -1234,32 +892,33 @@ int cFilterEEPG::GetChannelsMHW (const u_char * Data, int Length, int MHW)
//memcpy (C->Name, &Data[pName + 1], 256);
pName += (lenName + 1);
}
- C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1
- C->Src[0] = Source (); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!!
- C->Nid[0] = HILO16 (Channel->NetworkId);
- C->Tid[0] = HILO16 (Channel->TransportId);
- C->Sid[0] = HILO16 (Channel->ServiceId);
- tChannelID channelID = tChannelID (C->Src[0], C->Nid[0], C->Tid[0], C->Sid[0]);
+ //C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1
+ C->Src = Source (); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!!
+ C->Nid = HILO16 (Channel->NetworkId);
+ C->Tid = HILO16 (Channel->TransportId);
+ C->Sid = HILO16 (Channel->ServiceId);
+ tChannelID channelID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid);
cChannel *VC = GetChannelByID(channelID, true);
bool IsFound = (VC);
if(IsFound) {
- C->Src[0] = VC->Source();
+ C->Src = VC->Source();
}
CleanString (C->Name);
LogI(1, "|% 5d | %-26.26s | %-22.22s | %-3.3s | % 6d |\n", C->ChannelId
- , *tChannelID (C->Src[0], C->Nid[0], C->Tid[0], C->Sid[0]).ToString()
+ , *tChannelID (C->Src, C->Nid, C->Tid, C->Sid).ToString()
, C->Name, IsFound ? "YES" : "NO", C->SkyNumber);
Off += Size;
} //for loop
} //else nChannels > MAX_CHANNELS
- LoadEquivalentChannels ();
+ //LoadEquivalentChannels ();
+ EquivHandler->loadEquivalentChannelMap();
GetLocalTimeOffset (); //reread timing variables, only used for MHW
- return 2; //obviously, when you get here, channels are read succesfully, but since all channels are sent at once, you can stop now
+ return 2; //obviously, when you get here, channels are read successfully, but since all channels are sent at once, you can stop now
} //if nChannels == 0
LogE (0, prep("Warning: Trying to read Channels more than once!"));
-//you will only get here when GetChannelsMHW is called, and nChannels !=0, e.g. when multiple citpids cause channels to be read multiple times. Second time, do nothing, give error so that the rest of the chain is not restarted also.
+ //you will only get here when GetChannelsMHW is called, and nChannels !=0, e.g. when multiple citpids cause channels to be read multiple times. Second time, do nothing, give error so that the rest of the chain is not restarted also.
return 0;
}
@@ -1346,7 +1005,7 @@ int cFilterEEPG::GetThemesMHW2 (const u_char * Data, int Length)
if (Length >= (pSubThemeName + lenSubThemeName))
if (lenSubThemeName > 0)
if ((lenThemeName + lenSubThemeName + 2) < 256) {
- Themes[pThemeId][lenThemeName] = ' ';
+ Themes[pThemeId][lenThemeName] = '-';
decodeText2(&Data[pSubThemeName],lenSubThemeName,(char*)&Themes[pThemeId][lenThemeName + 1],256);
//memcpy (&Themes[pThemeId][lenThemeName + 1], &Data[pSubThemeName], lenSubThemeName);
}
@@ -1389,7 +1048,7 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse
if (TitleEventId != HILO32 (SD->EventId)) {
LogI(0, prep("ERROR, Title has EventId %08x and points to Summary with EventId %08x."), TitleEventId,
- HILO32 (SD->EventId));
+ HILO32 (SD->EventId));
return 0; //return empty string
}
@@ -1430,7 +1089,7 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse
("EEPGDEBUG: EventId %08x NumberOfBlocks %02x BlockId %08x SummTxtOffset %08x *p2: %02x Unkn1:%02x, Unkn2:%02x.",
HILO32 (SD->EventId), SD->NumberOfBlocks, HILO32 (SD->BlockId), HILO32 (SD->SummTxtOffset), *p2, SD->Unknown1,
SD->Unknown2);
- */
+ */
unsigned char *Text = NULL; //makes first realloc work like malloc
int TotLength = 0; //and also makes empty summaries if *p2 != 0x4e
if (SD->NumberOfBlocks > 1) {
@@ -1492,8 +1151,8 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse
break;
default:
LogE(0, prep("ERROR *p2 has strange value: EventId %08x NumberOfBlocks %02x BlockId %08x SummTxtOffset %08x *p2: %02x Unkn1:%02x, Unkn2:%02x."),
- HILO32 (SD->EventId), SD->NumberOfBlocks, HILO32 (SD->BlockId), HILO32 (SD->SummTxtOffset), *p2,
- SD->Unknown1, SD->Unknown2);
+ HILO32 (SD->EventId), SD->NumberOfBlocks, HILO32 (SD->BlockId), HILO32 (SD->SummTxtOffset), *p2,
+ SD->Unknown1, SD->Unknown2);
break;
} //end of switch
} //NrOfBlocks > 1
@@ -1503,40 +1162,50 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse
p += 29; //skip fixed part of block
if (SD->NumberOfBlocks == 1)
- p -= 4; //in this case there is NO summarytext AND no GBR??!!
+ p -= 4; //in this case there is NO summary text AND no GBR??!!
for (int i = 1; i < (SD->NumberOfBlocks - 1); i++) {
- LogD(3, prep("DEBUG: Extra Blockinfo: %02x %02x %02x %02x."), *p, *(p + 1), *(p + 2), *(p + 3));
- p += 4; //skip this extra blockinfo
+ LogD(3, prep("DEBUG: Extra Block info: %02x %02x %02x %02x."), *p, *(p + 1), *(p + 2), *(p + 3));
+ p += 4; //skip this extra block info
}
return (char *) Text;
}
-void cFilterEEPG::PrepareToWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES]) //gets a channel and returns an array of schedules that WriteToSchedule can write to. Call this routine before a batch of titles with the same ChannelId will be WriteToScheduled; batchsize can be 1
-{
- for (int eq = 0; eq < C->NumberOfEquivalences; eq++) {
- tChannelID channelID = tChannelID (C->Src[eq], C->Nid[eq], C->Tid[eq], C->Sid[eq]);
-#ifdef USE_NOEPG
- if (allowedEPG (channelID) && (channelID.Valid ()))
-#else
- if (channelID.Valid ()) //only add channels that are known to vdr
-#endif /* NOEPG */
- ps[eq] = s->AddSchedule (channelID); //open a a schedule for each equivalent channel
- else {
- ps[eq] = NULL;
- LogE(5, prep("ERROR: Titleblock has invalid (equivalent) channel ID: Equivalence: %i, Source:%x, C->Nid:%x,C->Tid:%x,C->Sid:%x."),
- eq, C->Src[eq], C->Nid[eq], C->Tid[eq], C->Sid[eq]);
- }
- }
-}
+/**
+ * \brief Prepare to Write to Schedule
+ *
+ * gets a channel and returns an array of schedules that WriteToSchedule can write to.
+ * Call this routine before a batch of titles with the same ChannelId will be WriteToScheduled; batchsize can be 1
+ *
+ * \param C channel to prepare
+ * \param s VDR epg schedules
+ * \param ps pointer to the schedules that WriteToSchedule can write to
+ */
+//void cFilterEEPG::PrepareToWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps/*[MAX_EQUIVALENCES]*/)
+//{
+// //for (int eq = 0; eq < C->NumberOfEquivalences; eq++) {
+// tChannelID channelID = tChannelID (C->Src/*[eq]*/, C->Nid/*[eq]*/, C->Tid/*[eq]*/, C->Sid/*[eq]*/);
+//#ifdef USE_NOEPG
+// if (allowedEPG (channelID) && (channelID.Valid ()))
+//#else
+// if (channelID.Valid ()) //only add channels that are known to vdr
+//#endif /* NOEPG */
+// ps/*[eq]*/ = s->AddSchedule (channelID); //open a a schedule for each equivalent channel
+// else {
+// ps/*[eq]*/ = NULL;
+//// LogE(5, prep("ERROR: Title block has invalid (equivalent) channel ID: Equivalence: %i, Source:%x, C->Nid:%x,C->Tid:%x,C->Sid:%x."),
+//// eq, C->Src[eq], C->Nid[eq], C->Tid[eq], C->Sid[eq]);
+// }
+// //}
+//}
-void cFilterEEPG::FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES])
-{
- for (int eq = 0; eq < C->NumberOfEquivalences; eq++)
- if (ps[eq]) {
- ps[eq]->Sort ();
- s->SetModified (ps[eq]);
- }
-}
+//void cFilterEEPG::FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES])
+//{
+// for (int eq = 0; eq < C->NumberOfEquivalences; eq++)
+// if (ps[eq]) {
+// ps[eq]->Sort ();
+// s->SetModified (ps[eq]);
+// }
+//}
/**
* \brief write event to schedule
@@ -1544,73 +1213,120 @@ void cFilterEEPG::FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule
* \param Duration the Duration of the event in minutes
* \param ps points to array of schedules ps[eq], where eq is equivalence number of the channel. If channelId is invalid then ps[eq]=NULL
*/
-void cFilterEEPG::WriteToSchedule (cSchedule * ps[MAX_EQUIVALENCES], unsigned short int NumberOfEquivalences, unsigned int EventId, unsigned int StartTime, unsigned int Duration, char *Text, char *SummText, unsigned short int ThemeId, unsigned short int TableId, unsigned short int Version, char Rating)
+void cFilterEEPG::WriteToSchedule (tChannelID channelID, cSchedules* pSchedules, unsigned int EventId, unsigned int StartTime, unsigned int Duration, char *Text, char *SummText, unsigned short int ThemeId, unsigned short int TableId, unsigned short int Version, char Rating)
{
bool WrittenTitle = false;
bool WrittenSummary = false;
- for (int eq = 0; eq < NumberOfEquivalences; eq++) {
- if (ps[eq]) {
- cEvent *Event = NULL;
+// for (int eq = 0; eq < NumberOfEquivalences; eq++) {
+ cSchedule* ps;
+ if (channelID.Valid ()) //only add channels that are known to VDR
+ ps = pSchedules->AddSchedule (channelID); //open or create new schedule
+ else {
+ ps = NULL;
+ }
+
+ cEvent *Event = NULL;
+ if (ps/*[eq]*/) {
- Event = (cEvent *) ps[eq]->GetEvent (EventId); //since Nagra uses consistent EventIds, try this first
+ Event = (cEvent *) ps->GetEvent (EventId); //since Nagra uses consistent EventIds, try this first
bool TableIdMatches = false;
if (Event)
TableIdMatches = (Event->TableID() == TableId);
if (!Event || !TableIdMatches || abs(Event->StartTime() - (time_t) StartTime) > Duration * 60) //if EventId does not match, or it matched with wrong TableId, then try with StartTime
- Event = (cEvent *) ps[eq]->GetEvent (EventId, StartTime);
-
- cEvent *newEvent = NULL;
- if (!Event) { //event is new
- Event = newEvent = new cEvent (EventId);
- Event->SetSeen ();
- } else if (Event->TableID() < TableId) { //existing table may not be overwritten
- RejectTableId++;
- //esyslog ("EEPGDEBUG: Rejecting Event, existing TableID:%x, new TableID:%x.", Event->TableID (),
- // TableId);
- Event = NULL;
- }
+ Event = (cEvent *) ps->GetEvent (EventId, StartTime);
+ }
+ cEvent *newEvent = NULL;
+ if (!Event) { //event is new
+ Event = newEvent = new cEvent (EventId);
+ Event->SetSeen ();
+ } else if (Event->TableID() < TableId) { //existing table may not be overwritten
+ RejectTableId++;
+ //esyslog ("EEPGDEBUG: Rejecting Event, existing TableID:%x, new TableID:%x.", Event->TableID (),
+ // TableId);
+ Event = NULL;
+ }
- if (Event) {
- Event->SetEventID (EventId); //otherwise the summary cannot be added later
- Event->SetTableID (TableId); //TableID 0 is reserved for external epg, will not be overwritten; the lower the TableID, the more actual it is
- Event->SetVersion (Version); //TODO use version and tableID to decide whether to update; TODO add language code
- Event->SetStartTime (StartTime);
- Event->SetDuration (Duration * 60);
- if (Rating) {
- Event->SetParentalRating(Rating);
+ if (Event) {
+ Event->SetEventID (EventId); //otherwise the summary cannot be added later
+ Event->SetTableID (TableId); //TableID 0 is reserved for external epg, will not be overwritten; the lower the TableID, the more actual it is
+ Event->SetVersion (Version); //TODO use version and tableID to decide whether to update; TODO add language code
+ Event->SetStartTime (StartTime);
+ Event->SetDuration (Duration * 60);
+ if (Rating) {
+ Event->SetParentalRating(Rating);
+ }
+ char *tmp;
+ if (Text != 0x00) {
+ WrittenTitle = true;
+ CleanString ((uchar *) Text);
+ Event->SetTitle (Text);
+ }
+ Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration);
+ Event->SetShortText (tmp);
+ free(tmp);
+ //strreplace(t, '|', '\n');
+ if (SummText != 0x00) {
+ WrittenSummary = true;
+ CleanString ((uchar *) SummText);
+
+ //Add themes and categories epgsearch style
+ char *theme;
+ Asprintf (&theme, "%s", Themes[ThemeId]);
+ if (theme && 0 != strcmp(theme,"")) {
+ char *category, *genre;
+ category = NULL;
+ genre = NULL;
+ char *split = strchr(theme, '-'); // Look for '-' delim to separate category from genre
+ if (split){
+ *split = 0;
+ category = theme;
+ genre = (split[1] == 0x20) ? split + 2 : split + 1;
+ }else{
+ category = theme;
}
- char *tmp;
- if (Text != 0x00) {
- WrittenTitle = true;
- CleanString ((uchar *) Text);
- Event->SetTitle (Text);
+ string fmt;
+ fmt = "%s";
+ if (stripspace(category)) {
+ fmt += "\nCategory: %s";
}
- Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration);
- Event->SetShortText (tmp);
- //strreplace(t, '|', '\n');
- if (SummText != 0x00) {
- WrittenSummary = true;
- CleanString ((uchar *) SummText);
- Event->SetDescription (SummText);
+ if (genre) {
+ fmt += "\nGenre: %s";
}
- free (tmp);
- if (newEvent)
- ps[eq]->AddEvent (newEvent);
- //newEvent->FixEpgBugs (); causes segfault
- }
+ Asprintf (&tmp, fmt.c_str(), SummText, category, stripspace (genre));
+
+ Event->SetDescription (tmp);
+ free(tmp);
+ free(theme);
+ }
+ else
+ Event->SetDescription (SummText);
+ }
+ if (ps && newEvent)
+ ps->AddEvent (newEvent);
+
+ EquivHandler->updateEquivalent(pSchedules, channelID, Event);
+
+ if (!ps) {
+ //the event is not send to VDR so it has to be deleted.
+ delete Event;
+ Event = NULL;
+ }
+
+ //newEvent->FixEpgBugs (); causes segfault
+ }
/* else
esyslog ("EEPG: ERROR, somehow not able to add/update event.");*///at this moment only reports RejectTableId events
- if (CheckLevel(4)) {
- isyslog ("EEPG: Title:%i, Summary:%i I would put into schedule:", TitleCounter, SummaryCounter);
- //isyslog ("C %s-%i-%i-%i\n", *cSource::ToString (C->Src[eq]), C->Nid[eq], C->Tid[eq], C->Sid[eq]);
- isyslog ("E %u %u %u 01 FF\n", EventId, StartTime, Duration * 60);
- isyslog ("T %s\n", Text);
- isyslog ("S %s - %d\'\n", Themes[ThemeId], Duration);
- isyslog ("D %s\n", SummText);
- isyslog ("e\nc\n.\n");
- }
- } //if ps[eq]
- } //for eq
+ if (CheckLevel(4)) {
+ isyslog ("EEPG: Title:%i, Summary:%i I would put into schedule:", TitleCounter, SummaryCounter);
+ //isyslog ("C %s-%i-%i-%i\n", *cSource::ToString (C->Src[eq]), C->Nid[eq], C->Tid[eq], C->Sid[eq]);
+ isyslog ("E %u %u %u 01 FF\n", EventId, StartTime, Duration * 60);
+ isyslog ("T %s\n", Text);
+ isyslog ("S %s - %d\'\n", Themes[ThemeId], Duration);
+ isyslog ("D %s\n", SummText);
+ isyslog ("e\nc\n.\n");
+ }
+// } //if ps[eq]
+// } //for eq
if (WrittenTitle)
TitleCounter++;
if (WrittenSummary)
@@ -1647,17 +1363,17 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
LogD(3, prep("DEBUG: ChannelId %04x, Blocklength %04x, NumberOfTitles %lu."), ChannelId, Blocklength,
NumberOfTitles);
- p += 4; //skip ChannelId and Blocklength
+ p += 4; //skip ChannelId and Block length
next_p = p + Blocklength;
if (next_p > DataEnd) { //only process if block is complete
LogE(0, prep("ERROR, Block exceeds end of Data. p:%p, Blocklength:%x,DataEnd:%p."), p, Blocklength, DataEnd);
return; //fatal error, this should never happen
}
- p += 4; //skip Titlenumber
+ p += 4; //skip Title number
sChannel *C = &sChannels[ChannelSeq[ChannelId]]; //find channel
- cSchedule *ps[MAX_EQUIVALENCES];
- PrepareToWriteToSchedule (C, s, ps);
+ //cSchedule *ps = NULL;//[MAX_EQUIVALENCES];
+ //PrepareToWriteToSchedule (C, s, ps);
for (int i = 0; i < NumberOfTitles; i++) { //process each title within block
sTitleNagraGuide *Title = (sTitleNagraGuide *) p;
@@ -1672,7 +1388,7 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
tmCurrent->tm_mon = CurrentMonth;
tmCurrent->tm_mday = MonthdayTitles;
tmCurrent->tm_hour = 0;
- tmCurrent->tm_min = StartTime; //if starttime is bigger than 1 hour, mktime will correct this!
+ tmCurrent->tm_min = StartTime; //if start time is bigger than 1 hour, mktime will correct this!
tmCurrent->tm_sec = 0;
tmCurrent->tm_isdst = -1; //now correct with daylight savings
if (MonthdayTitles < CurrentMonthday - 7) //the titles that are older than one week are not from the past, but from next month!
@@ -1686,7 +1402,7 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
//u_char *t2 = (u_char *) Data + HILO32 (Title->OffsetToText2);
if (t >= DataEnd)
LogE(0, prep("ERROR, Title Text out of range: t:%p, DataEnd:%p, Data:%p, Length:%i."), t, DataEnd, Data,
- Length);
+ Length);
else {
Asprintf (&Text, "%.*s", *t, t + 1);
//asprintf (&Text, "%.*s %.*s", *t, t + 1, *t2, t2 + 1); //FIXME second text string is not processed right now
@@ -1700,14 +1416,15 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
else
SummText = GetSummaryTextNagra (DataStartSummaries, HILO32 (Title->SumDataOffset), EventId);
- LogD(3, prep("DEBUG: Eventid: %08x ChannelId:%x, Starttime %02i:%02i, Duration %i, OffsetToText:%08x, OffsetToText2:%08x, SumDataOffset:%08x ThemeId:%x Title:%s \n SummaryText:%s"),
+ LogD(3, prep("DEBUG: Eventid: %08x ChannelId:%x, Start time %02i:%02i, Duration %i, OffsetToText:%08x, OffsetToText2:%08x, SumDataOffset:%08x ThemeId:%x Title:%s \n SummaryText:%s"),
EventId, ChannelId, Hours, Minutes, Title->Duration,
HILO32 (Title->OffsetToText), HILO32 (Title->OffsetToText2),
HILO32 (Title->SumDataOffset), Title->ThemeId, Text, SummText);
if (Themes[Title->ThemeId][0] == 0x00) //if detailed themeid is not known, get global themeid
Title->ThemeId &= 0xf0;
- WriteToSchedule (ps, C->NumberOfEquivalences, EventId, StartTime, Title->Duration, Text, SummText,
+
+ WriteToSchedule (tChannelID (C->Src, C->Nid, C->Tid, C->Sid), s, EventId, StartTime, Title->Duration, Text, SummText,
Title->ThemeId, NAGRA_TABLE_ID, Version);
if (Text != NULL)
@@ -1745,7 +1462,8 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
p += 30; //next title
} //end for titles
- FinishWriteToSchedule (C, s, ps);
+ //FinishWriteToSchedule (C, s, ps);
+ sortSchedules(s, tChannelID (C->Src, C->Nid, C->Tid, C->Sid));
p = next_p;
} while (p < DataEnd); //end of TitleBlock
}
@@ -1786,7 +1504,7 @@ int cFilterEEPG::GetThemesNagra (const u_char * Data, int Length, unsigned short
u_char *NewThemeId = DataStartTitles + HILO32 (TT->TitleOffset) + 28;
if (NewThemeId >= DataEndTitles)
LogE(0, prep("ERROR, ThemeId out of range: NewThemeId:%p, DataEndTitles:%p, DataStartTitles:%p."), NewThemeId,
- DataEndTitles, DataStartTitles);
+ DataEndTitles, DataStartTitles);
else {
//esyslog("EEPGDEBUG: NewThemeId:%02x, Text:%s.",*NewThemeId, Text);
if (Themes[*NewThemeId][0] != 0x00) { //theme is already filled, break off
@@ -1798,7 +1516,7 @@ int cFilterEEPG::GetThemesNagra (const u_char * Data, int Length, unsigned short
else if (ThemeId != *NewThemeId) { //different theme ids in block
if ((ThemeId & 0xf0) != (*NewThemeId & 0xf0)) { //major nible of themeid does not correspond
LogE(3, prep("ERROR, Theme has multiple indices which differ in major nibble, old index = %x, new index = %x. Ignoring both indices."),
- ThemeId, *NewThemeId);
+ ThemeId, *NewThemeId);
AnyDoubt = true;
break;
} else if ((ThemeId & 0x0f) != 0) //ThemeId is like 1a, 2a, not like 10,20. So it is minor in tree-structure, and it should be labeled in major part of tree
@@ -1820,7 +1538,7 @@ int cFilterEEPG::GetThemesNagra (const u_char * Data, int Length, unsigned short
Textlength = 63; //leave room for trailing NULL
if (Themes[ThemeId][0] != 0) {
LogE(0, prep("Trying to add new theme, but Id already exists. ThemeId = %x, Old theme with this Id:%s, new theme: %s."),
- ThemeId, Themes[ThemeId], Text);
+ ThemeId, Themes[ThemeId], Text);
continue;
}
memcpy (&Themes[ThemeId], Text, Textlength);
@@ -1860,20 +1578,20 @@ int cFilterEEPG::GetChannelsNagra (const u_char * Data, int Length)
sChannelsNagraGuide *Channel = (sChannelsNagraGuide *) p;
sChannel *C = &sChannels[j];
C->ChannelId = j + 1; //Nagra starts numbering at 1
- ChannelSeq[C->ChannelId] = j; //fill lookup table to go from channel-id to sequence nr in table; lookuptable starts with 0
+ ChannelSeq[C->ChannelId] = j; //fill lookup table to go from channel-id to sequence nr in table; lookup table starts with 0
C->SkyNumber = 0;
- C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1
- C->Src[0] = Source(); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!!
- C->Nid[0] = HILO16 (Channel->NetworkId);
- C->Tid[0] = HILO16 (Channel->TransportId);
- C->Sid[0] = HILO16 (Channel->ServiceId);
- tChannelID channelID = tChannelID(C->Src[0], C->Nid[0], C->Tid[0], C->Sid[0]);
+ //C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1
+ C->Src = Source(); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!!
+ C->Nid = HILO16 (Channel->NetworkId);
+ C->Tid = HILO16 (Channel->TransportId);
+ C->Sid = HILO16 (Channel->ServiceId);
+ tChannelID channelID = tChannelID(C->Src, C->Nid, C->Tid, C->Sid);
cChannel *VC = GetChannelByID(channelID, true);
bool IsFound = (VC);
if(IsFound) {
- strncpy((char*)(C->Name), VC->Name (), 64);
- C->Src[0] = VC->Source();
- CleanString (C->Name);
+ strncpy((char*)(C->Name), VC->Name (), 64);
+ C->Src = VC->Source();
+ CleanString (C->Name);
}
else
C->Name[0] = '\0'; //empty string
@@ -1925,12 +1643,13 @@ int cFilterEEPG::GetChannelsNagra (const u_char * Data, int Length)
isyslog ("EEPGDEBUG: Always0x81 is NOT 0x81:%x.", Channel->Always0x81);
if (Channel->Always0x44 != 0x44)
isyslog ("EEPGDEBUG: Always0x44 is NOT 0x44:%x.", Channel->Always0x44);
- */
+ */
}
if (p != DataEnd)
LogE(0, prep("Warning, possible problem at end of channel table; p = %p, DataEnd = %p"), p, DataEnd);
- LoadEquivalentChannels ();
+ //LoadEquivalentChannels ();
+ EquivHandler->loadEquivalentChannelMap();
return 2; //obviously, when you get here, channels are read succesfully, but since all channels are sent at once, you can stop now
}
@@ -1954,7 +1673,7 @@ int cFilterEEPG::GetNagra (const u_char * Data, int Length)
u_char *p = (u_char *) Data + 8;
if (*p != 0x01) {
LogE(0, prep("Error, Nagra first byte in table_id_extension 0x00 is not 0x01 but %02x. Format unknown, exiting."),
- *p);
+ *p);
return 0; //fatal error
}
p++; //skip 0x01 byte
@@ -2003,7 +1722,7 @@ int cFilterEEPG::GetNagra (const u_char * Data, int Length)
(0x0810) bouquet info; references to channels within a package, day 1 of the month
(0x0820) same day 2 of the month
(0x09f0) same day 31 of the month
- */
+ */
if (!(TBH->TableIdExtensionHigh >= 0x02 && TBH->TableIdExtensionHigh <= 0x07)) //here we regulate which tables we are testing
return (1);
@@ -2051,11 +1770,11 @@ void cFilterEEPG::ProcessNagra ()
NumberOfTables--;
}
- for (int i = 0; i < NagraCounter; i++) { //first prcoess all themes, since they all use the same codes
+ for (int i = 0; i < NagraCounter; i++) { //first process all themes, since they all use the same codes
unsigned short int TableIdExtension = NagraTIE[i];
int TIE = TableIdExtension - 0x0200; //from 0x0400 to 0x0200 -> titles
LogI(0, prep("Processing TableIdExtension:%04x"), TableIdExtension);
- GetTitlesNagra (buffer[TIE] + 4, bufsize[TIE] - 4, TableIdExtension); //assume title-reading is completed //TODO Language code terminatd by 0 is ignored
+ GetTitlesNagra (buffer[TIE] + 4, bufsize[TIE] - 4, TableIdExtension); //assume title-reading is completed //TODO Language code terminated by 0 is ignored
free (buffer[TIE]);
buffer[TIE] = NULL;
NumberOfTables--;
@@ -2066,7 +1785,7 @@ void cFilterEEPG::ProcessNagra ()
}
if (NumberOfTables != 0)
LogE(0, prep("ERROR, Not all tables processed and stream is already repeating. NumberOfTables = %i."),
- NumberOfTables);
+ NumberOfTables);
}
/**
@@ -2080,7 +1799,7 @@ int cFilterEEPG::GetTitlesMHW1 (const u_char * Data, int Length)
sTitleMHW1 *Title = (sTitleMHW1 *) Data;
if (Title->ChannelId == 0xff) { //FF is separator packet
if (memcmp (InitialTitle, Data, 46) == 0) { //data is the same as initial title //TODO use easier notation
- LogD(2, prep("End procesing titles"));
+ LogD(2, prep("End processing titles"));
return 2;
}
if (nTitles == 0)
@@ -2124,7 +1843,7 @@ int cFilterEEPG::GetTitlesMHW1 (const u_char * Data, int Length)
LogE(0, prep("Titles memory allocation error."));
return 0;
}
- T->Text[46] = '\0'; //end string with NULL character
+ //T->Text[46] = '\0'; //end string with NULL character
//memcpy (T->Text, &Title->Title, 23);
decodeText2((unsigned char *)&Title->Title, 23, (char*)T->Text, 47);
CleanString (T->Text);
@@ -2200,13 +1919,13 @@ int cFilterEEPG::GetTitlesMHW2 (const u_char * Data, int Length)
T->Duration = (((Data[Pos + 5] << 8) | Data[Pos + 6]) >> 4) * 60;
Len = Data[Pos + 7] & 0x3f;
//isyslog ("EEPGDebug: Len:%d", Len);
- T->Text = (unsigned char *) malloc (Len + 2);
+ T->Text = (unsigned char *) malloc (2 * Len + 1);
if (T->Text == NULL) {
LogE(0, prep("Titles memory allocation error."));
return 0; //fatal error
}
- T->Text[Len] = '\0'; //end string with NULL character
- decodeText2(&Data[Pos + 8],Len,(char*)T->Text,Len+1);
+ decodeText2(&Data[Pos + 8],Len,(char*)T->Text,2 * Len + 1);
+ //T->Text[Len] = '\0'; //end string with NULL character
//memcpy (T->Text, &Data[Pos + 8], Len);
CleanString (T->Text);
Pos += Len + 8; // Sub Theme starts here
@@ -2316,7 +2035,7 @@ int cFilterEEPG::GetSummariesMHW1 (const u_char * Data, int Length)
} //numreplays <10
else {
LogE(0, prep("Warning, number of replays %d > 10, cannot process."),
- Summary->NumReplays);
+ Summary->NumReplays);
return 1; //nonfatal error
}
} //length >11
@@ -2367,7 +2086,7 @@ int cFilterEEPG::GetSummariesMHW2 (const u_char * Data, int Length)
memcpy (&tmp[SummaryLength], &Data[Pos], lenText);
SummaryLength += lenText;
if (Loop > 1) {
- tmp[SummaryLength] = '\n';
+ tmp[SummaryLength] = ' ';// This is considered as an EPG bug in VDR '\n';
SummaryLength += 1;
}
} else
@@ -2376,14 +2095,14 @@ int cFilterEEPG::GetSummariesMHW2 (const u_char * Data, int Length)
Loop--;
}
}
- S->Text = (unsigned char *) malloc (SummaryLength + 2);
- S->Text[SummaryLength] = '\0'; //end string with NULL character
+ S->Text = (unsigned char *) malloc (2 * SummaryLength + 1);
if (S->Text == NULL) {
LogE(0, prep("Summaries memory allocation error."));
return 0; //fatal error
}
//memcpy (S->Text, tmp, SummaryLength);
- decodeText2(tmp,SummaryLength,(char*)S->Text,SummaryLength + 1);
+ //S->Text[SummaryLength] = '\0'; //end string with NULL character
+ decodeText2(tmp,SummaryLength,(char*)S->Text,2 * SummaryLength + 1);
CleanString (S->Text);
LogI(3, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text);
nSummaries++;
@@ -2405,7 +2124,8 @@ int cFilterEEPG::GetChannelsSKYBOX (const u_char * Data, int Length)
{
if (memcmp (InitialChannel, Data, 8) == 0) { //data is the same as initial title
- LoadEquivalentChannels ();
+ //LoadEquivalentChannels ();
+ EquivHandler->loadEquivalentChannelMap();
return 2;
} else {
if (nChannels == 0)
@@ -2452,13 +2172,13 @@ int cFilterEEPG::GetChannelsSKYBOX (const u_char * Data, int Length)
if (ChannelSeq.count (ChannelId) == 0) { //not found
C = &sChannels[nChannels];
C->ChannelId = ChannelId;
- C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1
- C->Src[0] = Source (); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!!
- C->Nid[0] = Nid;
- C->Tid[0] = Tid;
- C->Sid[0] = Sid;
+ //C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1
+ C->Src = Source (); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!!
+ C->Nid = Nid;
+ C->Tid = Tid;
+ C->Sid = Sid;
C->SkyNumber = SkyNumber;
- tChannelID channelID = tChannelID (C->Src[0], C->Nid[0], C->Tid[0], C->Sid[0]);
+ tChannelID channelID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid);
cChannel *VC = Channels.GetByChannelID (channelID, true);
bool IsFound = (VC);
if (IsFound)
@@ -2678,7 +2398,7 @@ void cFilterEEPG::FreeSummaries (void)
S = Summaries[i];
if (i < nSummaries - 1) {
S2 = Summaries[i + 1]; //look at next summary
- if (S->Text != S2->Text && S->Text != 0x00) //this is the last summary that points to this textblock; needed in case NumReplays > 1, multiple pointers to same textblock
+ if (S->Text != S2->Text && S->Text != 0x00) //this is the last summary that points to this text block; needed in case NumReplays > 1, multiple pointers to same textblock
free (S->Text);
} else if (S->Text != 0x00)
free (S->Text);
@@ -2711,13 +2431,14 @@ void cFilterEEPG::LoadIntoSchedule (void)
Title_t *T;
Summary_t *S;
int remembersummary;
-//keep statistics
+ //keep statistics
int SummariesNotFound = 0;
int NoSummary = 0;
int NotMatching = 0;
int LostSync = 0;
remembersummary = -1;
+ {
cSchedulesLock SchedulesLock (true);
cSchedules *s = (cSchedules *) cSchedules::Schedules (SchedulesLock);
if (s) {
@@ -2741,7 +2462,7 @@ void cFilterEEPG::LoadIntoSchedule (void)
if (!foundtitle) //no more titles with summaries
break;
if ((T->EventId == S->EventId) && (T->MjdTime == S->Replays[0].MjdTime)
- && ((T->ChannelId == S->Replays[0].ChannelId) || ((Format != SKY_IT) && (Format != SKY_UK)))) { //should always be true, titles and summaries are broadcasted in order...
+ && ((T->ChannelId == S->Replays[0].ChannelId) || ((Format != SKY_IT) && (Format != SKY_UK)))) { //should always be true, titles and summaries are broadcasted in order...
LogD(3, prep("T->EventId == S->EventId"));
//MjdTime = 0 for all but SKY
//S->ChannelId must be equal to T->ChannelId only for SKY; in MHW1 S->ChannelId overrides T->ChannelId when NumReplays > 1
@@ -2762,8 +2483,9 @@ void cFilterEEPG::LoadIntoSchedule (void)
//channelids are sequentially numbered and sent in MHW1 and MHW2, but not in SKY, so we need to lookup the table index
sChannel *C = &sChannels[ChannelSeq[ChannelId]]; //find channel
- cSchedule *p[MAX_EQUIVALENCES];
- PrepareToWriteToSchedule (C, s, p);
+ //cSchedule *p;//[MAX_EQUIVALENCES];
+ //PrepareToWriteToSchedule (C, s, p);
+ tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid);
char rating = 0x00;
if ((Format == SKY_IT || Format == SKY_UK) && T->Rating) { //TODO only works on OTV for now
@@ -2774,10 +2496,11 @@ void cFilterEEPG::LoadIntoSchedule (void)
TableId = T->TableId;
}
- WriteToSchedule (p, C->NumberOfEquivalences, T->EventId, StartTime, T->Duration / 60, (char *) T->Text,
+ WriteToSchedule (chanID, s, T->EventId, StartTime, T->Duration / 60, (char *) T->Text,
(char *) S->Text, T->ThemeId, TableId, 0, rating);
+ sortSchedules(s, chanID);
- FinishWriteToSchedule (C, s, p);
+ //FinishWriteToSchedule (C, s, p);
//Replays--;
//if ((S->NumReplays != 0) && (Replays > 0)) { //when replays are used, all summaries of the replays are stored consecutively; currently only CSAT
//j++; //move to next summary
@@ -2789,8 +2512,8 @@ void cFilterEEPG::LoadIntoSchedule (void)
} //while
while (index < S->NumReplays);
-//TODO: why load events that have already past, and then run Cleanup
-//end of putting title and summary in schedule
+ //TODO: why load events that have already past, and then run Cleanup
+ //end of putting title and summary in schedule
i++; //move to next title
} //if T->EventId == S->EventId
else {
@@ -2806,19 +2529,21 @@ void cFilterEEPG::LoadIntoSchedule (void)
//esyslog ("EEPG Error: could not find summary for summary-available Title %d.", i);
esyslog
("EEPG: Error, summary not found for EventId %08x Titlenr %d:SummAv:%x,Unknown1:%x,Unknown2:%x,Un3:%x,Name:%s.",
- T->EventId, i, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text);
+ T->EventId, i, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text);
/* write Title info to schedule */
sChannel *C = &sChannels[ChannelSeq[T->ChannelId]]; //find channel
- cSchedule *p[MAX_EQUIVALENCES];
- PrepareToWriteToSchedule (C, s, p);
+ //cSchedule *p;//[MAX_EQUIVALENCES];
+ tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid);
+ //PrepareToWriteToSchedule (C, s, p);
char rating = 0x00;
if ((Format == SKY_IT || Format == SKY_UK) && T->Rating) { //TODO only works on OTV for now
rating = T->Rating;
}
- WriteToSchedule (p, C->NumberOfEquivalences, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text,
+ WriteToSchedule (chanID, s, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text,
NULL, T->ThemeId, DEFAULT_TABLE_ID, 0, rating);
- FinishWriteToSchedule (C, s, p);
+ //FinishWriteToSchedule (C, s, p);
+ sortSchedules(s, chanID);
SummariesNotFound++;
i++; //move to next title, for this one no summary can be found
@@ -2832,21 +2557,23 @@ void cFilterEEPG::LoadIntoSchedule (void)
} //while title
} // if s
else
- esyslog ("EEPG Error: could not lock schedules.");
+ LogE (0, prep("Error: could not lock schedules."));
+ }//release ScheduleLock
cSchedules::Cleanup (true); //deletes all past events
- isyslog ("EEPG: found %i equivalents channels", nEquivChannels);
+ //isyslog ("EEPG: found %i equivalents channels", nEquivChannels);
isyslog ("EEPG: found %i themes", nThemes);
isyslog ("EEPG: found %i channels", nChannels);
isyslog ("EEPG: found %i titles", nTitles);
- isyslog ("EEPG: of which %i reported to have no summary available; skipping these BIENTOT titles", NoSummary);
+ if (NoSummary != 0)
+ isyslog ("EEPG: of which %i reported to have no summary available; skipping these BIENTOT titles", NoSummary);
isyslog ("EEPG: found %i summaries", nSummaries);
if (SummariesNotFound != 0)
esyslog ("EEPG: %i summaries not found", SummariesNotFound);
if (NotMatching > nSummaries)
LogI (0, prep("Warning: lost sync %i times, summary did not match %i times."),
- LostSync, NotMatching);
+ LostSync, NotMatching);
FreeSummaries (); //do NOT free channels, themes and bouquets here because they will be reused in SKY!
FreeTitles ();
@@ -2871,624 +2598,13 @@ void cFilterEEPG::AddFilter (u_short Pid, u_char Tid, unsigned char Mask)
}
}
-namespace SI
-{
- enum DescriptorTagExt {
- DishRatingDescriptorTag = 0x89,
- DishShortEventDescriptorTag = 0x91,
- DishExtendedEventDescriptorTag = 0x92,
- DishSeriesDescriptorTag = 0x96,
- };
-
- // typedef InheritEnum< DescriptorTagExt, SI::DescriptorTag > ExtendedDescriptorTag;
-
-/*extern const char *getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte = NULL);
-extern bool convertCharacterTable(const char *from, size_t fromLength, char *to, size_t toLength, const char *fromCode);
-extern bool SystemCharacterTableIsSingleByte;*/
-class cEIT2:public SI::EIT
-{
-public:
- cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool OnlyRunningStatus = false);
-};
-
-cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool OnlyRunningStatus)
- : SI::EIT (Data, false)
-{
- //LogD(2, prep("cEIT2::cEIT2"));
- if (Tid > 0 && Format == DISH_BEV) Tid--;
-
- if (!CheckCRCAndParse ()) {
- LogD(2, prep("!CheckCRCAndParse ()"));
- return;
- }
-
- bool searchOtherSatPositions = Format == DISH_BEV;
-
- tChannelID channelID (Source, getOriginalNetworkId (), getTransportStreamId (), getServiceId ());
- cChannel *channel = GetChannelByID (channelID, searchOtherSatPositions);
- if (!channel) {
- LogD(3, prep("!channel channelID: %s"), *channelID.ToString());
- return; // only collect data for known channels
- }
-
- LogD(4, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format);
-
-#ifdef USE_NOEPG
- // only use epg from channels not blocked by noEPG-patch
- tChannelID kanalID;
- kanalID = channel->GetChannelID ();
- if (!allowedEPG (kanalID))
- return;
-#endif /* NOEPG */
-
- cSchedule *pSchedule = (cSchedule *) Schedules->GetSchedule (channel, true);
-
- bool Empty = true;
- bool Modified = false;
- bool HasExternalData = false;
- time_t SegmentStart = 0;
- time_t SegmentEnd = 0;
-
- SI::EIT::Event SiEitEvent;
- for (SI::Loop::Iterator it; eventLoop.getNext (SiEitEvent, it);) {
- bool ExternalData = false;
- // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
- if (SiEitEvent.getStartTime () == 0 || (SiEitEvent.getStartTime () > 0 && SiEitEvent.getDuration () == 0))
- continue;
- Empty = false;
- if (!SegmentStart)
- SegmentStart = SiEitEvent.getStartTime ();
- SegmentEnd = SiEitEvent.getStartTime () + SiEitEvent.getDuration ();
- cEvent *newEvent = NULL;
- cEvent *rEvent = NULL;
- cEvent *pEvent = (cEvent *) pSchedule->GetEvent (SiEitEvent.getEventId (), SiEitEvent.getStartTime ());
- if (!pEvent) {
- if (OnlyRunningStatus)
- continue;
- // If we don't have that event yet, we create a new one.
- // Otherwise we copy the information into the existing event anyway, because the data might have changed.
- pEvent = newEvent = new cEvent (SiEitEvent.getEventId ());
- if (!pEvent)
- continue;
- } else {
- // We have found an existing event, either through its event ID or its start time.
- pEvent->SetSeen ();
- // If the existing event has a zero table ID it was defined externally and shall
- // not be overwritten.
- if (pEvent->TableID () == 0x00) {
-#ifdef USE_DDEPGENTRY
- if (pEvent->Version () == getVersionNumber ()) {
- if (Setup.MixEpgAction == 0)
- continue;
- //printf("in");
- //printf("%s", pEvent->GetTimeString());
- // to use the info of the original epg, update the extern one,
- // if it has less info
- SI::Descriptor * d;
- SI::ExtendedEventDescriptors * ExtendedEventDescriptors = NULL;
- //SI::ExtendedEventDescriptor *eed = NULL;
- SI::ShortEventDescriptor * ShortEventDescriptor = NULL;
- //SI::ShortEventDescriptor *sed = NULL;
- //SI::TimeShiftedEventDescriptor *tsed = NULL;
- //cLinkChannels *LinkChannels = NULL;
- for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext (it2));) {
- if (d->getDescriptorTag () == SI::ShortEventDescriptorTag) {
- int LanguagePreferenceShort = -1;
- SI::ShortEventDescriptor * sed = (SI::ShortEventDescriptor *) d;
- if (I18nIsPreferredLanguage (Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort)
- || !ShortEventDescriptor) {
- delete ShortEventDescriptor;
- ShortEventDescriptor = sed;
- d = NULL; // so that it is not deleted
- }
- } else if (d->getDescriptorTag () == SI::ExtendedEventDescriptorTag) {
- int LanguagePreferenceExt = -1;
- bool UseExtendedEventDescriptor = false;
- SI::ExtendedEventDescriptor * eed = (SI::ExtendedEventDescriptor *) d;
- if (I18nIsPreferredLanguage (Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt)
- || !ExtendedEventDescriptors) {
- delete ExtendedEventDescriptors;
- ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
- UseExtendedEventDescriptor = true;
- }
- if (UseExtendedEventDescriptor) {
- ExtendedEventDescriptors->Add (eed);
- d = NULL; // so that it is not deleted
- }
- if (eed->getDescriptorNumber () == eed->getLastDescriptorNumber ())
- UseExtendedEventDescriptor = false;
- }
- delete d;
- }
- if (pEvent) {
- if (ShortEventDescriptor) {
- char buffer[256];
- if (ShortEventDescriptor->text.getText (buffer, sizeof (buffer)) && pEvent->ShortText ()
- && (strlen (ShortEventDescriptor->text.getText (buffer, sizeof (buffer))) >
- strlen (pEvent->ShortText ()))) {
- pEvent->SetShortText (ShortEventDescriptor->text.getText (buffer, sizeof (buffer)));
- pEvent->FixEpgBugs ();
- }
- }
- if (ExtendedEventDescriptors) {
- char buffer[ExtendedEventDescriptors->getMaximumTextLength (": ") + 1];
- //pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": "));
- if (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": ")
- && pEvent->Description ()
- && (strlen (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": ")) >
- strlen (pEvent->Description ()))) {
- pEvent->SetDescription (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": "));
- pEvent->FixEpgBugs ();
- }
- }
- }
- delete ExtendedEventDescriptors;
- delete ShortEventDescriptor;
- continue;
- }
-#else
- if (pEvent->Version () == getVersionNumber ())
- continue;
-#endif /* DDEPGENTRY */
- HasExternalData = ExternalData = true;
- }
- // If the new event has a higher table ID, let's skip it.
- // The lower the table ID, the more "current" the information.
- else if (Tid > pEvent->TableID ())
- continue;
- // If the new event comes from the same table and has the same version number
- // as the existing one, let's skip it to avoid unnecessary work.
- // Unfortunately some stations (like, e.g. "Premiere") broadcast their EPG data on several transponders (like
- // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on
- // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned
- // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
- else if (Tid == pEvent->TableID() && pEvent->Version() == getVersionNumber())
- continue;
- }
- if (!ExternalData) {
- pEvent->SetEventID (SiEitEvent.getEventId ()); // unfortunately some stations use different event ids for the same event in different tables :-(
- pEvent->SetTableID (Tid);
- pEvent->SetStartTime (SiEitEvent.getStartTime ());
- pEvent->SetDuration (SiEitEvent.getDuration ());
- }
- if (newEvent)
- pSchedule->AddEvent (newEvent);
- if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
-#ifdef USE_DDEPGENTRY
- if (Setup.DisableVPS == 0 && SiEitEvent.getRunningStatus () >= SI::RunningStatusNotRunning)
-#else
- if (SiEitEvent.getRunningStatus () >= SI::RunningStatusNotRunning)
-#endif /* DDEPGENTRY */
- pSchedule->SetRunningStatus (pEvent, SiEitEvent.getRunningStatus (), channel);
- }
- if (OnlyRunningStatus)
- continue; // do this before setting the version, so that the full update can be done later
- pEvent->SetVersion (getVersionNumber());
-
- int LanguagePreferenceShort = -1;
- int LanguagePreferenceExt = -1;
- bool UseExtendedEventDescriptor = false;
- SI::Descriptor * d;
- SI::ExtendedEventDescriptors * ExtendedEventDescriptors = NULL;
- SI::ShortEventDescriptor * ShortEventDescriptor = NULL;
- //SI::DishDescriptor *DishExtendedEventDescriptor = NULL;
- SI::DishDescriptor *DishEventDescriptor = NULL;
- //uchar DishTheme = 0, DishCategory = 0;
-
-
- cLinkChannels *LinkChannels = NULL;
- cComponents *Components = NULL;
- for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext (it2));) {
- if (ExternalData && d->getDescriptorTag () != SI::ComponentDescriptorTag) {
- delete d;
- LogD(2, prep("continue:d->getDescriptorTAG():%x)"), d->getDescriptorTag ());
- continue;
- }
-
- //LogD(2, prep("EEPGDEBUG:d->getDescriptorTAG():%x)"), d->getDescriptorTag ());
-
- switch (d->getDescriptorTag ()) {
- case SI::ExtendedEventDescriptorTag: {
- SI::ExtendedEventDescriptor * eed = (SI::ExtendedEventDescriptor *) d;
- if (I18nIsPreferredLanguage (Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt)
- || !ExtendedEventDescriptors) {
- delete ExtendedEventDescriptors;
- ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
- UseExtendedEventDescriptor = true;
- }
- if (UseExtendedEventDescriptor) {
- ExtendedEventDescriptors->Add (eed);
- d = NULL; // so that it is not deleted
- }
- if (eed->getDescriptorNumber () == eed->getLastDescriptorNumber ())
- UseExtendedEventDescriptor = false;
- }
- break;
- case SI::ShortEventDescriptorTag: {
- SI::ShortEventDescriptor * sed = (SI::ShortEventDescriptor *) d;
- if (I18nIsPreferredLanguage (Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort)
- || !ShortEventDescriptor) {
- delete ShortEventDescriptor;
- ShortEventDescriptor = sed;
- d = NULL; // so that it is not deleted
- }
- }
- break;
-#if APIVERSNUM > 10711
- case SI::ContentDescriptorTag: {
- SI::ContentDescriptor *cd = (SI::ContentDescriptor *)d;
- SI::ContentDescriptor::Nibble Nibble;
- int NumContents = 0;
- uchar Contents[MaxEventContents] = { 0 };
- for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3); ) {
- if (NumContents < MaxEventContents) {
- Contents[NumContents] = ((Nibble.getContentNibbleLevel1() & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF);
- NumContents++;
- }
- if (DishEventDescriptor && NumContents == 1) {
- DishEventDescriptor->setContent(Nibble);
- }
- //LogD(2, prep("EEPGDEBUG:Nibble:%x-%x-%x-%x)"), Nibble.getContentNibbleLevel1(),Nibble.getContentNibbleLevel2()
- // , Nibble.getUserNibble1(), Nibble.getUserNibble2());
-
- }
- pEvent->SetContents(Contents);
- }
- break;
-#endif
- case SI::ParentalRatingDescriptorTag: {
- int LanguagePreferenceRating = -1;
- SI::ParentalRatingDescriptor *prd = (SI::ParentalRatingDescriptor *)d;
- SI::ParentalRatingDescriptor::Rating Rating;
- for (SI::Loop::Iterator it3; prd->ratingLoop.getNext(Rating, it3); ) {
- if (I18nIsPreferredLanguage(Setup.EPGLanguages, Rating.languageCode, LanguagePreferenceRating)) {
- int ParentalRating = (Rating.getRating() & 0xFF);
- switch (ParentalRating) {
- // values defined by the DVB standard (minimum age = rating + 3 years):
- case 0x01 ... 0x0F:
- ParentalRating += 3;
- break;
- // values defined by broadcaster CSAT (now why didn't they just use 0x07, 0x09 and 0x0D?):
- case 0x11:
- ParentalRating = 10;
- break;
- case 0x12:
- ParentalRating = 12;
- break;
- case 0x13:
- ParentalRating = 16;
- break;
- default:
- ParentalRating = 0;
- }
- pEvent->SetParentalRating(ParentalRating);
- }
- }
- }
- break;
- case SI::PDCDescriptorTag: {
- SI::PDCDescriptor * pd = (SI::PDCDescriptor *) d;
- time_t now = time (NULL);
- struct tm tm_r;
- struct tm t = *localtime_r (&now, &tm_r); // this initializes the time zone in 't'
- t.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
- int month = t.tm_mon;
- t.tm_mon = pd->getMonth () - 1;
- t.tm_mday = pd->getDay ();
- t.tm_hour = pd->getHour ();
- t.tm_min = pd->getMinute ();
- t.tm_sec = 0;
- if (month == 11 && t.tm_mon == 0) // current month is dec, but event is in jan
- t.tm_year++;
- else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
- t.tm_year--;
- time_t vps = mktime (&t);
- pEvent->SetVps (vps);
- }
- break;
- case SI::TimeShiftedEventDescriptorTag: {
- SI::TimeShiftedEventDescriptor * tsed = (SI::TimeShiftedEventDescriptor *) d;
- cSchedule *rSchedule =
- (cSchedule *) Schedules->
- GetSchedule (tChannelID (Source, channel->Nid (), channel->Tid (), tsed->getReferenceServiceId ()));
- if (!rSchedule)
- break;
- rEvent = (cEvent *) rSchedule->GetEvent (tsed->getReferenceEventId ());
- if (!rEvent)
- break;
- pEvent->SetTitle (rEvent->Title ());
- pEvent->SetShortText (rEvent->ShortText ());
- pEvent->SetDescription (rEvent->Description ());
- }
- break;
- case SI::LinkageDescriptorTag: {
- SI::LinkageDescriptor * ld = (SI::LinkageDescriptor *) d;
- tChannelID linkID (Source, ld->getOriginalNetworkId (), ld->getTransportStreamId (), ld->getServiceId ());
- if (ld->getLinkageType () == 0xB0) { // Premiere World
- time_t now = time (NULL);
- bool hit = SiEitEvent.getStartTime () <= now
- && now < SiEitEvent.getStartTime () + SiEitEvent.getDuration ();
- if (hit) {
- char linkName[ld->privateData.getLength () + 1];
- strn0cpy (linkName, (const char *) ld->privateData.getData (), sizeof (linkName));
- // TODO is there a standard way to determine the character set of this string?
- cChannel *link = Channels.GetByChannelID (linkID);
- if (link != channel) { // only link to other channels, not the same one
- //fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX
- if (link) {
- if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3)
- link->SetName (linkName, "", "");
- } else if (Setup.UpdateChannels >= 4) {
- cChannel *transponder = channel;
- if (channel->Tid () != ld->getTransportStreamId ())
- transponder = Channels.GetByTransponderID (linkID);
- link =
- Channels.NewChannel (transponder, linkName, "", "", ld->getOriginalNetworkId (),
- ld->getTransportStreamId (), ld->getServiceId ());
- }
- if (link) {
- if (!LinkChannels)
- LinkChannels = new cLinkChannels;
- LinkChannels->Add (new cLinkChannel (link));
- }
- } else
- channel->SetPortalName (linkName);
- }
- }
- }
- break;
- case SI::ComponentDescriptorTag: {
- SI::ComponentDescriptor * cd = (SI::ComponentDescriptor *) d;
- uchar Stream = cd->getStreamContent ();
- uchar Type = cd->getComponentType ();
- //if (1 <= Stream && Stream <= 3 && Type != 0) { // 1=video, 2=audio, 3=subtitles
- if (1 <= Stream && Stream <= 6 && Type != 0) { // 1=MPEG2-video, 2=MPEG1-audio, 3=subtitles, 4=AC3-audio, 5=H.264-video, 6=HEAAC-audio
- if (!Components)
- Components = new cComponents;
- char buffer[Utf8BufSize (256)];
- Components->SetComponent (Components->NumComponents (), Stream, Type,
- I18nNormalizeLanguageCode (cd->languageCode),
- cd->description.getText (buffer, sizeof (buffer)));
- }
- }
- break;
- case SI::DishExtendedEventDescriptorTag: {
- SI::UnimplementedDescriptor *deed = (SI::UnimplementedDescriptor *)d;
- if (!DishEventDescriptor) {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- DishEventDescriptor->setExtendedtData(Tid+1, deed->getData());
- HasExternalData = true;
- }
- break;
- case SI::DishShortEventDescriptorTag: {
- SI::UnimplementedDescriptor *dsed = (SI::UnimplementedDescriptor *)d;
- if (!DishEventDescriptor) {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- DishEventDescriptor->setShortData(Tid+1, dsed->getData());
- HasExternalData = true;
- }
- break;
- case SI::DishRatingDescriptorTag: {
- if (d->getLength() == 4) {
- if (!DishEventDescriptor) {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- uint16_t rating = d->getData().TwoBytes(2);
- DishEventDescriptor->setRating(rating);
- }
- }
- break;
- case SI::DishSeriesDescriptorTag: {
- if (d->getLength() == 10) {
- //LogD(2, prep("DishSeriesDescriptorTag: %s)"), (const char*) d->getData().getData());
- if (!DishEventDescriptor) {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- DishEventDescriptor->setEpisodeInfo(d->getData());
- }
-// else {
-// LogD(2, prep("DishSeriesDescriptorTag length: %d)"), d->getLength());
-// }
- }
- break;
- default:
- break;
- }
- delete d;
- }
-
- if (!rEvent) {
- if (ShortEventDescriptor) {
- char buffer[Utf8BufSize (256)];
- unsigned char *f;
- int l = ShortEventDescriptor->name.getLength();
- f = (unsigned char *) ShortEventDescriptor->name.getData().getData();
- decodeText2 (f, l, buffer, sizeof (buffer));
- //ShortEventDescriptor->name.getText(buffer, sizeof(buffer));
- LogD(2, prep("Title: %s Decoded: %s"), f, buffer);
- pEvent->SetTitle (buffer);
- l = ShortEventDescriptor->text.getLength();
- f = (unsigned char *) ShortEventDescriptor->text.getData().getData();
- decodeText2 (f, l, buffer, sizeof (buffer));
- //ShortEventDescriptor->text.getText(buffer, sizeof(buffer));
- pEvent->SetShortText (buffer);
- LogD(2, prep("ShortText: %s Decoded: %s"), f, buffer);
- } else if (!HasExternalData) {
- pEvent->SetTitle (NULL);
- pEvent->SetShortText (NULL);
- LogD(2, prep("!HasExternalData"));
- }
- if (ExtendedEventDescriptors) {
- char buffer[Utf8BufSize (ExtendedEventDescriptors->getMaximumTextLength (": ")) + 1];
- pEvent->SetDescription (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": "));
- } else if (!HasExternalData)
- pEvent->SetDescription (NULL);
-
- if (DishEventDescriptor) {
- if (DishEventDescriptor->getName())
- pEvent->SetTitle(DishEventDescriptor->getName());
- //LogD(2, prep("channelID: %s DishTitle: %s"), *channel->GetChannelID().ToString(), DishShortEventDescriptor->getText());
-// pEvent->SetDescription(DishExtendedEventDescriptor->getText());
- char *tmp;
- string fmt;
- fmt = "%s";
- if (0 != strcmp(DishEventDescriptor->getShortText(),"") && DishEventDescriptor->hasTheme()) {
- fmt += " - ";
- }
- fmt += "%s";
- if (DishEventDescriptor->hasTheme() && DishEventDescriptor->hasCategory()) {
- fmt += " ~ ";
- }
- fmt += "%s";
-
- Asprintf (&tmp, fmt.c_str(), DishEventDescriptor->getShortText()
- , DishEventDescriptor->getTheme()
- , DishEventDescriptor->getCategory());
- pEvent->SetShortText(tmp);
- //LogD(2, prep("EEPGDEBUG:DishTheme:%x-DishCategory:%x)"), DishTheme, DishCategory);
- free(tmp);
-
- fmt = "%s";
- if (0 != strcmp(DishEventDescriptor->getDescription(),"")
- && (0 != strcmp(DishEventDescriptor->getRating(),"")
- || 0 != strcmp(DishEventDescriptor->getStarRating(),""))) {
- fmt += "\n\nRating: ";
- }
- fmt += "%s %s";
- if (0 != strcmp(DishEventDescriptor->getProgramId(),"")) {
- fmt += "\n\nProgram ID: ";
- }
- fmt += "%s %s%s";
- time_t orgAirDate = DishEventDescriptor->getOriginalAirDate();
- char datestr [80];
- bool dateok = false;
- if (orgAirDate == 0) {
- dateok = strftime (datestr,80," Original Air Date: %a %b %d %Y",gmtime(&orgAirDate)) > 0;
- }
-
- Asprintf (&tmp, fmt.c_str(), DishEventDescriptor->getDescription()
- , DishEventDescriptor->getRating()
- , DishEventDescriptor->getStarRating()
- , DishEventDescriptor->getProgramId()
- , DishEventDescriptor->getSeriesId()
- , orgAirDate == 0 || !dateok ? "" : datestr);
- pEvent->SetDescription(tmp);
- free(tmp);
-
-
- //LogD(2, prep("DishDescription: %s"), DishExtendedEventDescriptor->getText());
- //LogD(2, prep("DishShortText: %s"), DishExtendedEventDescriptor->getShortText());
- }
- }
- delete ExtendedEventDescriptors;
- delete ShortEventDescriptor;
- delete DishEventDescriptor;
-
- pEvent->SetComponents (Components);
-
-// LogD(2, prep("channelID: %s Title: %s"), *channel->GetChannelID().ToString(), pEvent->Title());
-
-// if (pEvent->ChannelID() == tChannelID::FromString("S119.0W-4100-6-110-110")) {
-// LogD(2, prep("ID: %d Title: %s Time: %d Tid: 0x%x"), pEvent->EventID(), pEvent->Title(), pEvent->StartTime(), pEvent->TableID());
-// }
-
- if (!HasExternalData)
- pEvent->FixEpgBugs ();
- if (LinkChannels)
- channel->SetLinkChannels (LinkChannels);
- Modified = true;
-#ifdef USE_DDEPGENTRY
- //to avoid double epg-entrys from ext and int epg sources :EW
- if (pEvent && pEvent->TableID () != 0x00) {
- cEvent *pPreviousEvent = (cEvent *) pSchedule->GetPreviousEvent (pEvent);
- if (pPreviousEvent) {
- if (Setup.DoubleEpgAction == 0) {
- pPreviousEvent->SetStartTime (pEvent->StartTime ());
- pPreviousEvent->SetDuration (pEvent->Duration ());
- if (Setup.DisableVPS == 0) {
- if (channel)
- pPreviousEvent->SetRunningStatus (pEvent->RunningStatus (), channel);
- else
- pPreviousEvent->SetRunningStatus (pEvent->RunningStatus ());
- }
- // to use the info of the original epg, update the extern one,
- // if it has less info
- char buffer_short_intern[256];
- char buffer_short_extern[256];
- int len_short_intern = 0;
- int len_short_extern = 0;
- if (pEvent->ShortText ())
- len_short_intern =
- snprintf (buffer_short_intern, sizeof (buffer_short_intern) - 1, "%s", pEvent->ShortText ());
- if (pPreviousEvent->ShortText ())
- len_short_extern =
- snprintf (buffer_short_extern, sizeof (buffer_short_extern) - 1, "%s", pPreviousEvent->ShortText ());
- if (len_short_intern > 0) {
- if (len_short_extern < 1)
- pPreviousEvent->SetShortText (buffer_short_intern);
- else if (len_short_intern > len_short_extern)
- pPreviousEvent->SetShortText (buffer_short_intern);
- }
- if (pEvent->Description ()) {
- char buffer_title_intern[4096];
- char buffer_title_extern[4096];
- int len_title_intern = 0;
- int len_title_extern = 0;
- if (pEvent->Description ())
- len_title_intern =
- snprintf (buffer_title_intern, sizeof (buffer_title_intern) - 1, "%s", pEvent->Description ());
- if (pPreviousEvent->Description ())
- len_title_extern =
- snprintf (buffer_title_extern, sizeof (buffer_title_extern) - 1, "%s",
- pPreviousEvent->Description ());
- if (len_title_intern > 0) {
- if (len_title_extern < 1)
- pPreviousEvent->SetDescription (buffer_title_intern);
- else if (len_title_intern > len_title_extern)
- pPreviousEvent->SetDescription (buffer_title_intern);
- }
- }
- if (pPreviousEvent->Vps () == 0 && pEvent->Vps () != 0)
- pPreviousEvent->SetVps (pEvent->Vps ());
- pSchedule->DelEvent (pEvent);
- pPreviousEvent->FixEpgBugs ();
- } else
- pSchedule->DelEvent (pPreviousEvent);
- }
- }
-#endif /* DDEPGENTRY */
- }
- if (Empty && Tid == 0x4E && getSectionNumber () == 0)
- // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running
- pSchedule->ClrRunningStatus (channel);
- if (Tid == 0x4E)
- pSchedule->SetPresentSeen ();
- if (OnlyRunningStatus) {
- LogD(4, prep("OnlyRunningStatus"));
- return;
- }
- if (Modified) {
- pSchedule->Sort ();
- if (!HasExternalData)
- pSchedule->DropOutdated (SegmentStart, SegmentEnd, Tid, getVersionNumber ());
- Schedules->SetModified (pSchedule);
- }
- LogD(4, prep("end of cEIT2"));
-
-}
-//end of cEIT2
-
-} //end namespace SI
-
void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
{
/* for (int i = 0; i <= HIGHEST_FORMAT; i++)
esyslog ("EEPGDEBUG: Format %i on pid %x", i, UnprocessedFormat[i]); */
if (!FirstTime) {
- isyslog ("EEPG: found %i equivalents channels", nEquivChannels);
+ //isyslog ("EEPG: found %i equivalents channels", equiChanMap.size());
isyslog ("EEPG: found %i themes", nThemes);
isyslog ("EEPG: found %i channels", nChannels);
isyslog ("EEPG: found %i titles", nTitles);
@@ -3497,7 +2613,7 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
isyslog ("EEPG: written %i summaries", SummaryCounter);
isyslog ("EEPG: rejected %i titles/summaries because of higher TableId", RejectTableId);
//Send message when finished
- if (SetupPE.DisplayMessage) {
+ if (SetupPE->DisplayMessage) {
char *mesg;
Asprintf(&mesg, "EEPG: written %i summaries", SummaryCounter);
Skins.QueueMessage(mtInfo, mesg, 2);
@@ -3526,6 +2642,13 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
FreeTitles ();
FreeSummaries ();
+ // Enable EIT scan for all except DISH_BEV since it is already enabled
+ if (SetupPE->ProcessEIT && !UnprocessedFormat[EIT]
+ && !UnprocessedFormat[FREEVIEW] && !UnprocessedFormat[DISH_BEV]) {
+ UnprocessedFormat[EIT] = EIT_PID;
+ EquivHandler->loadEquivalentChannelMap();
+ }
+
//now start looking for next format to process
int pid;
for (int i = 0; i <= HIGHEST_FORMAT; i++){ //find first format that is detected
@@ -3550,15 +2673,13 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
memset (&InitialSummary, 0, 64);
NagraCounter = 0;
Version = -1; //because 0 can be a valid version number...
- nEquivChannels = 0;
nChannels = 0;
nThemes = 0;
EndChannels = false;
EndThemes = false;
switch (Format) {
case PREMIERE:
- if (!Matches (pid, 0xA0))
- Add (pid, 0xA0);
+ AddFilter (pid, 0xA0);
break;
case MHW1:
AddFilter (0xd3, 0x92); //ThemesMHW1//TODO: all filters are serialized, strictly speaking Themes is non-fatal...
@@ -3582,12 +2703,19 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
AddFilter (pid, 0xb0); //perhaps TID is equal to first data byte?
break;
case DISH_BEV:
- AddFilter (0x12, 0, 0); // event info, actual(0x4e)/other(0x4f) TS, present/following
+#if APIVERSNUM < 10726
+ AddFilter (EIT_PID, 0, 0); // event info, actual(0x4e)/other(0x4f) TS, present/following
+#endif
AddFilter (0x0300, 0, 0); // Dish Network EEPG event info, actual(0x4e)/other(0x4f) TS, present/following
AddFilter (0x0441, 0, 0); // Dish Network EEPG event info, actual(0x4e)/other(0x4f) TS, present/following
// AddFilter (0x0441, 0x50, 0xf0); // Bell ExpressVU EEPG
// AddFilter (0x0441, 0x60, 0xf0); // Bell ExpressVU EEPG
break;
+ case EIT:
+ AddFilter (pid, 0x4e, 0xfe); //event info, actual(0x4e)/other(0x4f) TS, present/following
+ AddFilter (pid, 0x50, 0xf0); //event info, actual TS, schedule(0x50)/schedule for future days(0x5X)
+ AddFilter (pid, 0x60, 0xf0); //event info, other TS, schedule(0x60)/schedule for future days(0x6X)
+ break;
default:
break;
}
@@ -3595,27 +2723,27 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const u_char *Data)
{
- //0x39 Viasat, 0x0300 Dish Network EEPG, 0x0441 Bell ExpressVU EEPG
- LogD(4, prep("Pid: 0x%02x Tid: %d Length: %d"), Pid, Tid, Length);
- cSchedulesLock SchedulesLock(true, 10);
+ //0x39 Viasat, 0x0300 Dish Network EEPG, 0x0441 Bell ExpressVU EEPG
+ LogD(4, prep("Pid: 0x%02x Tid: %d Length: %d"), Pid, Tid, Length);
+ cSchedulesLock SchedulesLock(true, 10);
+ cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock));
+ //Look for other satelite positions only if Dish/Bell ExpressVU for the moment hardcoded pid check
+ if(Schedules)
+ SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Pid == EIT_PID);
+
+ else//cEIT EIT (Schedules, Source (), Tid, Data);
+ {
+ // If we don't get a write lock, let's at least get a read lock, so
+ // that we can set the running status and 'seen' timestamp (well, actually
+ // with a read lock we shouldn't be doing that, but it's only integers that
+ // get changed, so it should be ok)
+ cSchedulesLock SchedulesLock;
cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock));
- //Look for other satelite positions only if Dish/Bell ExpressVU for the moment hardcoded pid check
if(Schedules)
- SI::cEIT2 EIT(Schedules, Source(), Tid, Data);
+ SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Pid == EIT_PID, true);
- else//cEIT EIT (Schedules, Source (), Tid, Data);
- {
- // If we don't get a write lock, let's at least get a read lock, so
- // that we can set the running status and 'seen' timestamp (well, actually
- // with a read lock we shouldn't be doing that, but it's only integers that
- // get changed, so it should be ok)
- cSchedulesLock SchedulesLock;
- cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock));
- if(Schedules)
- SI::cEIT2 EIT(Schedules, Source(), Tid, Data, true);
-
- //cEIT EIT (Schedules, Source (), Tid, Data, true);
- }
+ //cEIT EIT (Schedules, Source (), Tid, Data, true);
+ }
}
void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Length)
@@ -3678,9 +2806,11 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len
}
//Format = 0; // 0 = premiere, 1 = MHW1, 2 = MHW2, 3 = Sky Italy (OpenTV), 4 = Sky UK (OpenTV), 5 = Freesat (Freeview), 6 = Nagraguide
SI::Descriptor * d;
+ unsigned char nDescriptorTag;
for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext (it));) {
LogD(4, prep("EEPGDEBUG:d->getDescriptorTAG():%x,SI::PrivateTag:%x\n"), d->getDescriptorTag (), SI::PrivateDataSpecifierDescriptorTag);
- switch (d->getDescriptorTag ()) {
+ nDescriptorTag = d->getDescriptorTag ();
+ switch (nDescriptorTag) {
case SI::PrivateDataSpecifierDescriptorTag:
//esyslog ("prv: %d %08x\n", d->getLength (), d->getData ().FourBytes (2));
if (d->getLength () == 6 && d->getData ().FourBytes (2) == 0x000000be)
@@ -3753,10 +2883,11 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len
if (((Source() == cSource::FromString("S119.0W")
&& Transponder() == cChannel::Transponder(12472,'H'))
|| (Source() == cSource::FromString("S91.0W")
- && Transponder() == cChannel::Transponder(12224,'R')))
+ && Transponder() == cChannel::Transponder(12224,'V')))
&& !UnprocessedFormat[DISH_BEV]) {
UnprocessedFormat[DISH_BEV] = stream.getPid ();
}
+
} //if data[1] && data [3]
} //if streamtype
} //for loop that walks through streams
@@ -3774,19 +2905,20 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len
} //if pmtpid
else if (Source ()) {
- if ( Pid == 0x12 || Pid == 0x0300 || Pid == 0x0441 ) {
+ if ( Pid == EIT_PID || Pid == 0x0300 || Pid == 0x0441 ) {
if (Tid >= 0x4E)
ProccessContinuous(Pid, Tid, Length, Data);
return;
}
int Result;
switch (Tid) {
- case 0xA0: //TODO DPE test this missing break but it seems a bug
+ case 0xA0:
if ((Pid < 0x30) || (Pid > 0x37)) {
ProcessPremiere(Data);
break;
} //if citpid == 0xb11 Premiere
+ /* no break - used for sky also*/
case 0xa1:
case 0xa2:
case 0xa3:
@@ -4010,8 +3142,6 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len
} //closes SOURCE()
} //end of closing
-// --- cPluginEEPG ------------------------------------------------------
-
void cFilterEEPG::ProcessPremiere(const u_char *& Data)
{
@@ -4032,13 +3162,15 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
{
time_t firstTime = 0;
SI::Descriptor * d;
+ unsigned char nDescriptorTag;
bool UseExtendedEventDescriptor = false;
int LanguagePreferenceShort = -1;
int LanguagePreferenceExt = -1;
for (SI::Loop::Iterator it; (d = cit.eventDescriptors.getNext (it));) {
- switch (d->getDescriptorTag ()) {
+ nDescriptorTag = d->getDescriptorTag ();
+ switch (nDescriptorTag) {
case 0xF0: // order information
- if (SetupPE.OrderInfo) {
+ if (SetupPE->OrderInfo) {
static const char *text[] = {
trNOOP ("Ordernumber"),
trNOOP ("Price"),
@@ -4060,7 +3192,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
}
break;
case 0xF1: // parental rating
- if (SetupPE.RatingInfo) {
+ if (SetupPE->RatingInfo) {
char buff[512];
int p = 0;
const unsigned char *data = d->getData ().getData () + 2;
@@ -4096,7 +3228,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
case SI::ExtendedEventDescriptorTag: {
SI::ExtendedEventDescriptor * eed = (SI::ExtendedEventDescriptor *) d;
if (I18nIsPreferredLanguage (Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt)
- || !ExtendedEventDescriptors) {
+ || !ExtendedEventDescriptors) {
delete ExtendedEventDescriptors;
ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
UseExtendedEventDescriptor = true;
@@ -4112,7 +3244,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
case SI::ShortEventDescriptorTag: {
SI::ShortEventDescriptor * sed = (SI::ShortEventDescriptor *) d;
if (I18nIsPreferredLanguage (Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort)
- || !ShortEventDescriptor) {
+ || !ShortEventDescriptor) {
delete ShortEventDescriptor;
ShortEventDescriptor = sed;
d = NULL; // so that it is not deleted
@@ -4133,14 +3265,14 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
crc[0] = cit.getContentId ();
SI::PremiereContentTransmissionDescriptor * pct;
for (SI::Loop::Iterator it;
- (pct =
- (SI::PremiereContentTransmissionDescriptor *) cit.eventDescriptors.getNext (it,
- SI::
- PremiereContentTransmissionDescriptorTag));) {
+ (pct =
+ (SI::PremiereContentTransmissionDescriptor *) cit.eventDescriptors.getNext (it,
+ SI::
+ PremiereContentTransmissionDescriptorTag));) {
int nid = pct->getOriginalNetworkId ();
int tid = pct->getTransportStreamId ();
int sid = pct->getServiceId ();
- if (SetupPE.FixEpg) {
+ if (SetupPE->FixEpg) {
if (nid == 133) {
if (tid == 0x03 && sid == 0xf0) {
tid = 0x02;
@@ -4162,11 +3294,6 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
}
tChannelID channelID (Source (), nid, tid, sid);
cChannel *channel = Channels.GetByChannelID (channelID, true);
-#ifdef USE_NOEPG
- // only use epg from channels not blocked by noEPG-patch
- if (!allowedEPG (channelID))
- continue;
-#endif /* NOEPG */
if (!channel)
continue;
@@ -4186,12 +3313,10 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
for (SI::Loop::Iterator it2; sd.startTimeLoop.getNext (st, it2);) {
time_t StartTime = st.getStartTime (mjd);
time_t EndTime = StartTime + cit.getDuration ();
- int runningStatus = (StartTime < now
- && now < EndTime) ? SI::RunningStatusRunning : ((StartTime - 30 < now
- && now <
- StartTime) ? SI::
- RunningStatusStartsInAFewSeconds
- : SI::RunningStatusNotRunning);
+ int runningStatus =
+ (StartTime < now && now < EndTime) ? SI::RunningStatusRunning :
+ ((StartTime - 30 < now && now < StartTime) ?
+ SI::RunningStatusStartsInAFewSeconds : SI::RunningStatusNotRunning);
bool isOpt = false;
if (index++ == 0 && nCount > 1)
isOpt = true;
@@ -4234,7 +3359,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
ShortEventDescriptor->name.getText (buffer, sizeof (buffer));
if (isOpt) {
char buffer2[sizeof (buffer) + 32];
- snprintf (buffer2, sizeof (buffer2), optPats[SetupPE.OptPat], buffer, optCount);
+ snprintf (buffer2, sizeof (buffer2), optPats[SetupPE->OptPat], buffer, optCount);
pEvent->SetTitle (buffer2);
} else
pEvent->SetTitle (buffer);
@@ -4247,7 +3372,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
}
if (order || rating) {
int len = (pEvent->Description ()? strlen (pEvent->Description ()) : 0) +
- (order ? strlen (order) : 0) + (rating ? strlen (rating) : 0);
+ (order ? strlen (order) : 0) + (rating ? strlen (rating) : 0);
char buffer[len + 32];
buffer[0] = 0;
if (pEvent->Description ())
@@ -4287,6 +3412,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
}
+// --- cPluginEEPG ------------------------------------------------------
class cPluginEEPG:public cPlugin
{
@@ -4320,7 +3446,7 @@ cPluginEEPG::cPluginEEPG (void)
void cPluginEEPG::CheckCreateFile(const char* Name, const char *fileContent[])
{
FILE *File;
- string FileName = string(ConfDir) + "/" + Name;
+ string FileName = string(cSetupEEPG::getInstance()->getConfDir()) + "/" + Name;
File = fopen(FileName.c_str(), "r");
if (File == NULL) {
LogE (0, prep("Error opening file '%s', %s"), FileName.c_str(), strerror (errno));
@@ -4354,12 +3480,12 @@ bool cPluginEEPG::Start (void)
isyslog ("Attached EEPG filter to device %d", i);
}
}
- ConfDir = NULL;
+ char *ConfDir = NULL;
// Initialize any background activities the plugin shall perform.
DIR *ConfigDir;
- if (ConfDir == NULL) {
- Asprintf (&ConfDir, "%s/eepg", cPlugin::ConfigDirectory ());
- }
+ //if (ConfDir == NULL) {
+ Asprintf (&ConfDir, "%s/eepg", cPlugin::ConfigDirectory ());
+ //}
ConfigDir = opendir (ConfDir);
if (ConfigDir == NULL) {
esyslog ("EEPG: Error opening directory '%s', %s", ConfDir, strerror (errno));
@@ -4369,6 +3495,8 @@ bool cPluginEEPG::Start (void)
isyslog ("EEPG: Success creating directory '%s'", ConfDir);
}
}
+ cSetupEEPG::getInstance()->setConfDir(ConfDir);
+
CheckCreateFile(EEPG_FILE_EQUIV, FileEquivalences);
CheckCreateFile("sky_it.dict", SkyItDictionary);
CheckCreateFile("sky_uk.dict", SkyUkDictionary);
@@ -4396,6 +3524,14 @@ bool cPluginEEPG::Start (void)
for (int i = 0; i < NumberOfAvailableSources; i++)
isyslog ("EEPG: Available sources:%s.", *cSource::ToString (AvailableSources[i]));
+#if APIVERSNUM > 10725
+ new cEEpgHandler();
+#endif
+ EquivHandler = new cEquivHandler();
+
+ if (ConfDir) {
+ free (ConfDir);
+ }
closedir(ConfigDir);
return true;
}
@@ -4412,15 +3548,19 @@ void cPluginEEPG::Stop (void)
}
// Clean up after yourself!
- if (ConfDir) {
- free (ConfDir);
- }
+// if (ConfDir) {
+// free (ConfDir);
+// }
if (sky_tables[0]) {
- free(sky_tables[0]);
+ free(sky_tables[0]);
}
if (sky_tables[1]) {
- free(sky_tables[1]);
+ free(sky_tables[1]);
}
+ if (EquivHandler) {
+ delete EquivHandler;
+ }
+
}
cMenuSetupPage *cPluginEEPG::SetupMenu (void)
@@ -4443,18 +3583,20 @@ bool cPluginEEPG::SetupParse (const char *Name, const char *Value)
if (!strcasecmp (Name, "OptionPattern"))
- SetupPE.OptPat = atoi (Value);
+ SetupPE->OptPat = atoi (Value);
else if (!strcasecmp (Name, "OrderInfo"))
- SetupPE.OrderInfo = atoi (Value);
+ SetupPE->OrderInfo = atoi (Value);
else if (!strcasecmp (Name, "RatingInfo"))
- SetupPE.RatingInfo = atoi (Value);
+ SetupPE->RatingInfo = atoi (Value);
else if (!strcasecmp (Name, "FixEpg"))
- SetupPE.FixEpg = atoi (Value);
+ SetupPE->FixEpg = atoi (Value);
else if (!strcasecmp (Name, "DisplayMessage"))
- SetupPE.DisplayMessage = atoi (Value);
+ SetupPE->DisplayMessage = atoi (Value);
#ifdef DEBUG
else if (!strcasecmp (Name, "LogLevel"))
- SetupPE.LogLevel = atoi (Value);
+ SetupPE->LogLevel = atoi (Value);
+ else if (!strcasecmp (Name, "ProcessEIT"))
+ SetupPE->ProcessEIT = atoi (Value);
#endif
else
return false;