summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--eepg.c757
-rw-r--r--eepg.h14
-rw-r--r--epghandler.c41
-rw-r--r--epghandler.h3
-rw-r--r--equivhandler.c265
-rw-r--r--equivhandler.h39
-rw-r--r--setupeepg.c7
-rw-r--r--setupeepg.h17
-rw-r--r--util.c209
-rw-r--r--util.h32
11 files changed, 837 insertions, 549 deletions
diff --git a/Makefile b/Makefile
index a2d413e..b63221f 100644
--- a/Makefile
+++ b/Makefile
@@ -65,7 +65,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o
+OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o equivhandler.o util.o
ifdef DBG
CXXFLAGS += -g
diff --git a/eepg.c b/eepg.c
index ae358e9..3fce100 100644
--- a/eepg.c
+++ b/eepg.c
@@ -43,6 +43,8 @@
#endif
#include "log.h"
#include "setupeepg.h"
+#include "equivhandler.h"
+#include "util.h"
#include <map>
#include <string>
@@ -56,20 +58,6 @@
#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
@@ -85,6 +73,7 @@ template <class T> T REALLOC(T Var, size_t Size)
}
using namespace std;
+using namespace util;
const char *optPats[] = {
"%s",
@@ -111,7 +100,7 @@ char *cs_hexdump (int m, const uchar * buf, int n)
}
cSetupEEPG* SetupPE = cSetupEEPG::getInstance();
-
+cEquivHandler* EquivHandler;
// --- cMenuSetupPremiereEpg ------------------------------------------------------------
@@ -181,11 +170,8 @@ 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
-static multimap<string, string> equiChanMap;
#ifdef USE_NOEPG
@@ -213,7 +199,7 @@ 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
@@ -261,14 +247,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:
@@ -361,8 +346,8 @@ struct hufftab {
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
@@ -443,6 +428,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);
@@ -780,120 +768,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];
@@ -941,7 +822,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) {
@@ -965,7 +846,7 @@ bool cFilterEEPG::InitDictionary (void)
FileName += "/freesat.t1";
if (!load_freesat_file (1, FileName.c_str()))
return false;
- FileName = ConfDir;
+ FileName = cSetupEEPG::getInstance()->getConfDir();
FileName += "/freesat.t2";
return load_freesat_file (2, FileName.c_str());
} else
@@ -1001,175 +882,20 @@ void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize
//LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize);
}
-void loadEquivalentChannelMap (void)
-{
- char Buffer[1024];
- char *Line;
- FILE *File;
- string FileName = string(ConfDir) + "/" + EEPG_FILE_EQUIV;
- multimap<string,string>::iterator it,it2;
- pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
-
- //TODO DPE add code to reload if file is changed
- if (equiChanMap.size() > 0)
- return;
+void sortSchedules(cSchedules * Schedules, tChannelID channelID){
+ LogD(3, prep("Start sortEquivalent %s"), *channelID.ToString());
- File = fopen (FileName.c_str(), "r");
- if (File) {
- memset (Buffer, 0, sizeof (Buffer));
- char origChanID[256];
- char equiChanID[256];
- char source[256];
- int nid = 0;
- int tid = 0;
- int sid = 0;
- int rid = 0;
- while ((Line = fgets (Buffer, sizeof (Buffer), File)) != NULL) {
- Line = compactspace (skipspace (stripspace (Line)));
- if (!isempty (Line)) {
- if (sscanf (Line, "%[^ ] %[^ ] %[^\n]\n", origChanID, equiChanID, source) == 3) {
- if (origChanID[0] != '#' && origChanID[0] != ';') {
- nid = 0;
- tid = 0;
- sid = 0;
- rid = 0;
- if (sscanf (origChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4)
- if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) {
- if (sscanf (origChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) != 5) {
- rid = 0;
- }
- tChannelID OriginalChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid);
- bool found = false;
- //int i = 0;
- 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"), origChanID); //TODO: skip this ing?
- continue;
- }
- if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) {
- if (sscanf (equiChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid)
- != 5) {
- rid = 0;
- }
- tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid);
- cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); //TODO use valid function?
- if (EquivChannel) {
- ret = equiChanMap.equal_range(*OriginalChID.ToString());
- for (it=ret.first; it!=ret.second; ++it)
- if ((*it).second == *OriginalChID.ToString()) {
- found = true;
- break;
- }
-
- if (!found) {
- string origCh(*OriginalChID.ToString());
- string equiCh(*EquivChID.ToString());
- equiChanMap.insert(pair<string,string>(origCh.c_str(),equiCh.c_str()));
- LogD(4, prep("Found %s equivalent to %s. origCh %s"), *EquivChID.ToString(), *OriginalChID.ToString(), origCh.c_str());
- for ( it2=equiChanMap.begin() ; it2 != equiChanMap.end(); it2++ )
- LogD(3, prep("Original ID %s <-> Equivalent ID %s"), (*it2).first.c_str(), it2->second.c_str());
- }
- } else
- LogI(0, prep("Warning, not found equivalent channel \'%s\' in channels.conf"), equiChanID);
- }
- } //if scanf string1
- } //if string1
- } //if scanf
- } //if isempty
- } //while
- fclose (File);
- LogD(3, prep("Loaded %i equivalents."), equiChanMap.size());
- for ( it2=equiChanMap.begin() ; it2 != equiChanMap.end(); it2++ )
- LogD(3, prep("Original ID %s <-> Equivalent ID %s"), (*it2).first.c_str(), it2->second.c_str());
- } //if file
+ cChannel *pChannel = GetChannelByID (channelID, false);
+ cSchedule *pSchedule;
+ if (pChannel) {
+ pSchedule = (cSchedule *) (Schedules->GetSchedule(pChannel, true));
+ pSchedule->Sort();
+ Schedules->SetModified(pSchedule);
+ }
+ if (EquivHandler->getEquiChanMap().count(*channelID.ToString()) > 0)
+ EquivHandler->sortEquivalents(channelID, Schedules);
}
-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 origChanID[256];
- char equiChanID[256];
- char source[256];
- int nid;
- int tid;
- int sid;
- int rid;
- while ((Line = fgets (Buffer, sizeof (Buffer), File)) != NULL) {
- Line = compactspace (skipspace (stripspace (Line)));
- if (!isempty (Line)) {
- if (sscanf (Line, "%[^ ] %[^ ] %[^\n]\n", origChanID, equiChanID, source) == 3) {
- if (origChanID[0] != '#' && origChanID[0] != ';') {
- nid = 0;
- tid = 0;
- sid = 0;
- rid = 0;
- if (sscanf (origChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4)
- if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) {
- if (sscanf (origChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) != 5) {
- rid = 0;
- }
- tChannelID OriginalChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid);
- bool found = false;
- int i = 0;
- sChannel *C = NULL;
- while (i < nChannels && (!found)) {
- C = &sChannels[i];
- if (C->Src[0] == (unsigned int)cSource::FromString (source) && C->Nid[0] == nid
- && C->Tid[0] == tid && C->Sid[0] == sid)
- 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."),
- origChanID);
- } else {
- cChannel *OriginalChannel = Channels.GetByChannelID (OriginalChID, false);
- if (!OriginalChannel)
- LogI(2, prep("Warning, not found epg channel \'%s\' in channels.conf. Equivalence is assumed to be valid, but perhaps you should check the entry in the equivalents file"), origChanID); //TODO: skip this ing?
- if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) {
- if (sscanf (equiChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid)
- != 5) {
- rid = 0;
- }
- tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid);
- 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"), equiChanID);
- }
- } //else !found
- } //if scanf string1
- } //if string1
- } //if scanf
- } //if isempty
- } //while
- fclose (File);
- } //if file
-} //end of loadequiv
-
-//end of loadequiv
/**
@@ -1231,27 +957,28 @@ 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 successfully, but since all channels are sent at once, you can stop now
} //if nChannels == 0
@@ -1518,32 +1245,32 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse
* \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::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]);
+// }
+//}
/**
* \brief write event to schedule
@@ -1551,104 +1278,111 @@ 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);
- }
- char *tmp;
- if (Text != 0x00) {
- WrittenTitle = true;
- CleanString ((uchar *) Text);
- Event->SetTitle (Text);
+ 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;
}
- 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;
- }
- string fmt;
- fmt = "%s";
- if (stripspace(category)) {
- fmt += "\nCategory: %s";
- }
- if (genre) {
- fmt += "\nGenre: %s";
- }
- Asprintf (&tmp, fmt.c_str(), SummText, category, stripspace (genre));
-
- Event->SetDescription (tmp);
- free(tmp);
- free(theme);
+ string fmt;
+ fmt = "%s";
+ if (stripspace(category)) {
+ fmt += "\nCategory: %s";
}
- else
- Event->SetDescription (SummText);
+ if (genre) {
+ fmt += "\nGenre: %s";
}
- 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);
+ //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)
@@ -1694,8 +1428,8 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
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;
@@ -1745,7 +1479,8 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor
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)
@@ -1783,7 +1518,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
}
@@ -1900,17 +1636,17 @@ int cFilterEEPG::GetChannelsNagra (const u_char * Data, int Length)
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; 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();
+ C->Src = VC->Source();
CleanString (C->Name);
}
else
@@ -1968,7 +1704,8 @@ int cFilterEEPG::GetChannelsNagra (const u_char * Data, int Length)
}
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
}
@@ -2443,7 +2180,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)
@@ -2490,13 +2228,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)
@@ -2756,6 +2494,7 @@ void cFilterEEPG::LoadIntoSchedule (void)
int LostSync = 0;
remembersummary = -1;
+ {
cSchedulesLock SchedulesLock (true);
cSchedules *s = (cSchedules *) cSchedules::Schedules (SchedulesLock);
if (s) {
@@ -2800,8 +2539,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
@@ -2812,10 +2552,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
@@ -2848,15 +2589,17 @@ void cFilterEEPG::LoadIntoSchedule (void)
/* 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
@@ -2870,11 +2613,12 @@ 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);
@@ -2927,74 +2671,10 @@ class cEIT2:public SI::EIT
{
public:
cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid = false, bool OnlyRunningStatus = false);
-protected:
- void updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent);
+//protected:
+// void updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent);
};
-void cEIT2::updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent){
- multimap<string,string>::iterator it;
- pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
-
- LogD(3, prep("Start updateEquivalent %s"), *channelID.ToString());
-
- ret = equiChanMap.equal_range(*channelID.ToString());
- for (it=ret.first; it!=ret.second; ++it) {
- LogD(1, prep("equivalent channel exists"));
- tChannelID equChannelID (tChannelID::FromString((*it).second.c_str()));
- cChannel *equChannel = GetChannelByID (equChannelID, false);
- if (equChannel) {
- LogD(3, prep("found Equivalent channel %s"), *equChannelID.ToString());
- cSchedule *pSchedule = (cSchedule *) Schedules->GetSchedule (equChannel, true);
- cEvent *pEqvEvent = (cEvent *) pSchedule->GetEvent (pEvent->EventID(), pEvent->StartTime());
- if (pEqvEvent) {
- LogD(1, prep("equivalent event exists"));
- if (pEqvEvent == pEvent) {
- LogD(1, prep("equal event exists"));
-
- } else {
- LogD(1, prep("remove equivalent"));
- pSchedule->DelEvent(pEqvEvent);
- cEvent* newEvent = new cEvent (pEvent->EventID());
- newEvent->SetTableID (pEvent->TableID());
- newEvent->SetStartTime (pEvent->StartTime());
- newEvent->SetDuration (pEvent->Duration());
- newEvent->SetVersion (pEvent->Version());
-// newEvent->SetContents(pEvent->Contents());
- newEvent->SetParentalRating(pEvent->ParentalRating());
- newEvent->SetVps (pEvent->Vps());
- newEvent->SetTitle (pEvent->Title ());
- newEvent->SetShortText (pEvent->ShortText ());
- newEvent->SetDescription (pEvent->Description ());
-// newEvent->SetComponents (pEvent->Components());
- newEvent->FixEpgBugs ();
-
- pSchedule->AddEvent(newEvent);
- pSchedule->Sort ();
-
- }
-
- } else {
- LogD(1, prep("equivalent event does not exist"));
- cEvent* newEvent = new cEvent (pEvent->EventID());
- newEvent->SetTableID (pEvent->TableID());
- newEvent->SetStartTime (pEvent->StartTime());
- newEvent->SetDuration (pEvent->Duration());
- newEvent->SetVersion (pEvent->Version());
-// newEvent->SetContents(pEvent->Contents());
- newEvent->SetParentalRating(pEvent->ParentalRating());
- newEvent->SetVps (pEvent->Vps());
- newEvent->SetTitle (pEvent->Title ());
- newEvent->SetShortText (pEvent->ShortText ());
- newEvent->SetDescription (pEvent->Description ());
-// newEvent->SetComponents (pEvent->Components());
- newEvent->FixEpgBugs ();
-
- pSchedule->AddEvent(newEvent);
- pSchedule->Sort ();
- }
- }
- }
-}
cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid, bool OnlyRunningStatus)
: SI::EIT (Data, false)
@@ -3572,7 +3252,7 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
}
}
#endif /* DDEPGENTRY */
- updateEquivalent(Schedules, channel->GetChannelID(), pEvent);
+ EquivHandler->updateEquivalent(Schedules, channel->GetChannelID(), pEvent);
}
if (Empty && Tid == 0x4E && getSectionNumber () == 0)
// ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running
@@ -3584,10 +3264,9 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat
return;
}
if (Modified) {
- pSchedule->Sort ();
if (!HasExternalData)
pSchedule->DropOutdated (SegmentStart, SegmentEnd, Tid, getVersionNumber ());
- Schedules->SetModified (pSchedule);
+ sortSchedules(Schedules, channel->GetChannelID());
}
LogD(4, prep("end of cEIT2"));
@@ -3602,7 +3281,7 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
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);
@@ -3644,7 +3323,7 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false)
if (SetupPE->ProcessEIT && !UnprocessedFormat[EIT]
&& !UnprocessedFormat[FREEVIEW] && !UnprocessedFormat[DISH_BEV]) {
UnprocessedFormat[EIT] = EIT_PID;
- loadEquivalentChannelMap();
+ EquivHandler->loadEquivalentChannelMap();
}
//now start looking for next format to process
@@ -3671,7 +3350,6 @@ 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;
@@ -4141,8 +3819,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)
{
@@ -4418,6 +4094,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data)
}
+// --- cPluginEEPG ------------------------------------------------------
class cPluginEEPG:public cPlugin
{
@@ -4451,7 +4128,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));
@@ -4485,12 +4162,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));
@@ -4500,6 +4177,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);
@@ -4530,7 +4209,11 @@ bool cPluginEEPG::Start (void)
#if APIVERSNUM > 10725
new cEEpgHandler();
#endif
+ EquivHandler = new cEquivHandler();
+ if (ConfDir) {
+ free (ConfDir);
+ }
closedir(ConfigDir);
return true;
}
@@ -4547,15 +4230,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]);
}
if (sky_tables[1]) {
free(sky_tables[1]);
}
+ if (EquivHandler) {
+ delete EquivHandler;
+ }
+
}
cMenuSetupPage *cPluginEEPG::SetupMenu (void)
diff --git a/eepg.h b/eepg.h
index d306ca0..18690de 100644
--- a/eepg.h
+++ b/eepg.h
@@ -1,13 +1,11 @@
//#define DEBUG false
//#define DEBUG_STARTTIME false
-#define EEPG_FILE_EQUIV "eepg.equiv"
-
#define MAX_THEMES 2046 //this should always be >=256, or Nagra will go wrong!!
#define MAX_CHANNELS 2048
#define MAX_TITLES 262144
-#define MAX_EQUIVALENCES 8 //the number of equivalences one channel can have
+//#define MAX_EQUIVALENCES 8 //the number of equivalences one channel can have
//Formats (need to be consecutively numbered):
//#define PREMIERE 0
@@ -53,11 +51,11 @@ typedef struct
{
unsigned short int ChannelId;
unsigned short int SkyNumber;
- unsigned short int NumberOfEquivalences;//original channel sets this value to 1, every equivalent channel adds 1
- unsigned int Src[MAX_EQUIVALENCES];
- unsigned short int Nid[MAX_EQUIVALENCES];
- unsigned short int Tid[MAX_EQUIVALENCES];
- unsigned short int Sid[MAX_EQUIVALENCES];
+ //unsigned short int NumberOfEquivalences;//original channel sets this value to 1, every equivalent channel adds 1
+ unsigned int Src;//[MAX_EQUIVALENCES];
+ unsigned short int Nid;//[MAX_EQUIVALENCES];
+ unsigned short int Tid;//[MAX_EQUIVALENCES];
+ unsigned short int Sid;//[MAX_EQUIVALENCES];
unsigned char Name[64];
} sChannel;
diff --git a/epghandler.c b/epghandler.c
index 2e50c33..ecf5de9 100644
--- a/epghandler.c
+++ b/epghandler.c
@@ -8,14 +8,17 @@
#include "epghandler.h"
#if APIVERSNUM > 10725
#include "log.h"
+#include "equivhandler.h"
#include <vdr/sources.h>
cEEpgHandler::cEEpgHandler() {
LogD(4, prep("cEEpgHandler()"));
-
+ equivHandler = new cEquivHandler();
}
cEEpgHandler::~cEEpgHandler() {
+ delete equivHandler;
+ equivHandler = NULL;
}
bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule,
@@ -26,6 +29,19 @@ bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule,
int nid = Schedule->ChannelID().Nid();
if ((nid >= 0x1001 && nid <= 0x100B) || nid == 0x101 || nid == 0x100)
return true;
+
+ //TODO!!! not for commit upsteram
+ if (EitEvent->getDurationHour() > 10) {
+ LogD(3, prep("Event longer than 10h Duration:%d DurationHour:%d StartTimeHour:%d"), EitEvent->getDuration(), EitEvent->getDurationHour(), EitEvent->getStartTimeHour());
+ const cEvent* exEvent = Schedule->GetEventAround(EitEvent->getStartTime()+EitEvent->getDuration()/2);
+ if (exEvent) {
+ LogD(3, prep("10h Existing event %s startTime %d"), exEvent->Title(), exEvent->StartTime());
+ return true;
+ }
+ }
+ //if (EitEvent->getDurationHour() > 3)
+// return true;
+
return false;
// return true;
}
@@ -107,6 +123,19 @@ bool cEEpgHandler::HandleEvent(cEvent* Event) {
if (!Event->Description() && !origDescription.empty()) {
Event->SetDescription(origDescription.c_str());
}
+
+ if (equivHandler->getEquiChanMap().count(*Event->ChannelID().ToString()) <= 0)
+ return true;
+
+ equivHandler->updateEquivalent(Event->ChannelID(), Event);
+
+// cSchedulesLock SchedulesLock (true);
+// cSchedules *s = (cSchedules *) cSchedules::Schedules (SchedulesLock);
+// if (s) {
+// equivHandler->updateEquivalent(s, Event->ChannelID(), Event);
+// } else
+// LogE (0, prep("Error: could not lock schedules."));
+
//TODO just to see the difference
//else if (!origDescription.empty() && !origDescription.compare(Event->Description())) {
// origDescription.append(" | EIT: ");
@@ -118,7 +147,17 @@ bool cEEpgHandler::HandleEvent(cEvent* Event) {
}
bool cEEpgHandler::SortSchedule(cSchedule* Schedule) {
+
Schedule->Sort();
+
+ //NOK
+// cSchedulesLock SchedulesLock (true);
+// cSchedules *s = (cSchedules *) cSchedules::Schedules (SchedulesLock);
+// if (s) {
+// equivHandler->sortEquivalents(Schedule->ChannelID(), s);
+// } else
+// LogE (0, prep("Error: could not lock schedules."));
+
return true;
}
diff --git a/epghandler.h b/epghandler.h
index 61f295b..e1c6915 100644
--- a/epghandler.h
+++ b/epghandler.h
@@ -12,6 +12,8 @@
#include <vdr/epg.h>
#include <string>
+class cEquivHandler;
+
class cEEpgHandler : public cEpgHandler {
public:
cEEpgHandler();
@@ -35,6 +37,7 @@ public:
private:
std::string origShortText;
std::string origDescription;
+ cEquivHandler* equivHandler;
};
#endif /*APIVERSNUM > 10725*/
diff --git a/equivhandler.c b/equivhandler.c
new file mode 100644
index 0000000..b10c004
--- /dev/null
+++ b/equivhandler.c
@@ -0,0 +1,265 @@
+/*
+ * equivhandler.cpp
+ *
+ * Created on: 19.5.2012
+ * Author: d.petrovski
+ */
+
+#include "equivhandler.h"
+#include "setupeepg.h"
+#include "log.h"
+#include "util.h"
+
+#include <string>
+
+using namespace util;
+
+multimap<string, string> cEquivHandler::equiChanMap;
+long cEquivHandler::equiChanFileTime = 0;
+
+cEquivHandler::cEquivHandler()
+{
+ loadEquivalentChannelMap();
+}
+
+cEquivHandler::~cEquivHandler()
+{
+ // TODO Auto-generated destructor stub
+}
+
+void cEquivHandler::loadEquivalentChannelMap (void)
+{
+ char Buffer[1024];
+ char *Line;
+ FILE *File;
+ string FileName = string(cSetupEEPG::getInstance()->getConfDir()) + "/" + EEPG_FILE_EQUIV;
+ multimap<string,string>::iterator it,it2;
+ pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
+
+ //Test if file is changed and reload
+ struct stat st;
+ if (stat(FileName.c_str(), &st)) {
+ LogE(0, prep("Error obtaining stats for '%s' "), FileName.c_str());
+ return;
+ }
+
+ if (equiChanMap.size() > 0 && equiChanFileTime == st.st_mtim.tv_nsec)
+ return;
+ else
+ equiChanMap.clear();
+
+
+ File = fopen (FileName.c_str(), "r");
+ if (File) {
+ memset (Buffer, 0, sizeof (Buffer));
+ char origChanID[256];
+ char equiChanID[256];
+ char source[256];
+ int nid = 0;
+ int tid = 0;
+ int sid = 0;
+ int rid = 0;
+ while ((Line = fgets (Buffer, sizeof (Buffer), File)) != NULL) {
+ Line = compactspace (skipspace (stripspace (Line)));
+ if (!isempty (Line)) {
+ if (sscanf (Line, "%[^ ] %[^ ] %[^\n]\n", origChanID, equiChanID, source) == 3) {
+ if (origChanID[0] != '#' && origChanID[0] != ';') {
+ nid = 0;
+ tid = 0;
+ sid = 0;
+ rid = 0;
+ if (sscanf (origChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4)
+ if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) {
+ if (sscanf (origChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) != 5) {
+ rid = 0;
+ }
+ tChannelID OriginalChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid);
+ bool found = false;
+ //int i = 0;
+ 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"), origChanID); //TODO: skip this ing?
+ continue;
+ }
+ if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) {
+ if (sscanf (equiChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid)
+ != 5) {
+ rid = 0;
+ }
+ tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid);
+ cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); //TODO use valid function?
+ if (EquivChannel) {
+ ret = equiChanMap.equal_range(*OriginalChID.ToString());
+ for (it=ret.first; it!=ret.second; ++it)
+ if ((*it).second == *OriginalChID.ToString()) {
+ found = true;
+ break;
+ }
+
+ if (!found) {
+ string origCh(*OriginalChID.ToString());
+ string equiCh(*EquivChID.ToString());
+ equiChanMap.insert(pair<string,string>(origCh.c_str(),equiCh.c_str()));
+ LogD(4, prep("Found %s equivalent to %s. origCh %s"), *EquivChID.ToString(), *OriginalChID.ToString(), origCh.c_str());
+ for ( it2=equiChanMap.begin() ; it2 != equiChanMap.end(); it2++ )
+ LogD(3, prep("Original ID %s <-> Equivalent ID %s"), (*it2).first.c_str(), it2->second.c_str());
+ }
+ } else
+ LogI(0, prep("Warning, not found equivalent channel \'%s\' in channels.conf"), equiChanID);
+ }
+ } //if scanf string1
+ } //if string1
+ } //if scanf
+ } //if isempty
+ } //while
+ fclose (File);
+ equiChanFileTime = st.st_mtim.tv_nsec;
+ LogD(2, prep("Loaded %i equivalents."), equiChanMap.size());
+ for ( it2=equiChanMap.begin() ; it2 != equiChanMap.end(); it2++ )
+ LogD(2, prep("Original ID %s <-> Equivalent ID %s"), (*it2).first.c_str(), it2->second.c_str());
+ } //if file
+}
+
+void cEquivHandler::updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent){
+ multimap<string,string>::iterator it;
+ pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
+
+ LogD(2, prep("Start updateEquivalent %s"), *channelID.ToString());
+
+ ret = equiChanMap.equal_range(*channelID.ToString());
+ for (it=ret.first; it!=ret.second; ++it) {
+ LogD(2, prep("equivalent channel exists"));
+ tChannelID equChannelID (tChannelID::FromString((*it).second.c_str()));
+ cChannel *equChannel = GetChannelByID (equChannelID, false);
+ if (equChannel) {
+ LogD(2, prep("found Equivalent channel %s"), *equChannelID.ToString());
+ cSchedule *pSchedule = (cSchedule *) Schedules->GetSchedule (equChannel, true);
+ cEvent *pEqvEvent = (cEvent *) pSchedule->GetEvent (pEvent->EventID(), pEvent->StartTime());
+ if (pEqvEvent) {
+ LogD(3, prep("equivalent event exists"));
+ if (pEqvEvent == pEvent) {
+ LogD(3, prep("equal event exists"));
+
+ } else {
+ LogD(2, prep("remove equivalent"));
+ pSchedule->DelEvent(pEqvEvent);
+ cEvent* newEvent = new cEvent (pEvent->EventID());
+ newEvent->SetTableID (pEvent->TableID());
+ newEvent->SetStartTime (pEvent->StartTime());
+ newEvent->SetDuration (pEvent->Duration());
+ newEvent->SetVersion (pEvent->Version());
+// newEvent->SetContents(pEvent->Contents());
+ newEvent->SetParentalRating(pEvent->ParentalRating());
+ newEvent->SetVps (pEvent->Vps());
+ newEvent->SetTitle (pEvent->Title ());
+ newEvent->SetShortText (pEvent->ShortText ());
+ newEvent->SetDescription (pEvent->Description ());
+// newEvent->SetComponents (pEvent->Components());
+ newEvent->FixEpgBugs ();
+
+ pSchedule->AddEvent(newEvent);
+
+ }
+
+ } else {
+ LogD(3, prep("equivalent event does not exist"));
+ cEvent* newEvent = new cEvent (pEvent->EventID());
+ newEvent->SetTableID (pEvent->TableID());
+ newEvent->SetStartTime (pEvent->StartTime());
+ newEvent->SetDuration (pEvent->Duration());
+ newEvent->SetVersion (pEvent->Version());
+// newEvent->SetContents(pEvent->Contents());
+ newEvent->SetParentalRating(pEvent->ParentalRating());
+ newEvent->SetVps (pEvent->Vps());
+ newEvent->SetTitle (pEvent->Title ());
+ newEvent->SetShortText (pEvent->ShortText ());
+ newEvent->SetDescription (pEvent->Description ());
+// newEvent->SetComponents (pEvent->Components());
+ newEvent->FixEpgBugs ();
+
+ pSchedule->AddEvent(newEvent);
+
+ }
+ }
+ }
+}
+
+void cEquivHandler::updateEquivalent(tChannelID channelID, cEvent *pEvent){
+ multimap<string,string>::iterator it;
+ pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
+
+ LogD(2, prep("Start updateEquivalent %s"), *channelID.ToString());
+
+ ret = equiChanMap.equal_range(*channelID.ToString());
+ for (it=ret.first; it!=ret.second; ++it) {
+ LogD(2, prep("equivalent channel exists"));
+ tChannelID equChannelID (tChannelID::FromString((*it).second.c_str()));
+ cEvent* newEvent = new cEvent (pEvent->EventID());
+ newEvent->SetTableID (pEvent->TableID());
+ newEvent->SetStartTime (pEvent->StartTime());
+ newEvent->SetDuration (pEvent->Duration());
+ newEvent->SetVersion (pEvent->Version());
+// newEvent->SetContents(pEvent->Contents());
+ newEvent->SetParentalRating(pEvent->ParentalRating());
+ newEvent->SetVps (pEvent->Vps());
+ newEvent->SetTitle (pEvent->Title ());
+ newEvent->SetShortText (pEvent->ShortText ());
+ newEvent->SetDescription (pEvent->Description ());
+// newEvent->SetComponents (pEvent->Components());
+ AddEvent(newEvent, equChannelID);
+ }
+}
+
+
+//cSchedule * findFisrtSchedule (cSchedule * Schedule) {
+// if (Schedule->Prev())
+// return findFisrtSchedule((cSchedule *)Schedule->Prev());
+// else
+// return Schedule;
+//}
+//
+//cSchedule * findSchedule (cSchedule * Schedule, tChannelID channelID) {
+// if (Schedule->ChannelID() == channelID)
+// return Schedule;
+//
+// if (Schedule->Next())
+// return findSchedule((cSchedule *)Schedule->Next(), channelID);
+// else
+// return NULL;
+//}
+//
+//cSchedule * findEqvSchedule (cSchedule * Schedule, tChannelID channelID) {
+// cSchedule* foundSchedule = findSchedule(findFisrtSchedule(Schedule),channelID);
+//
+// if (foundSchedule)
+// return foundSchedule;
+//
+// cSchedule* sch = new cSchedule(channelID);
+// Schedule->Insert(sch);
+// return sch;
+//}
+
+
+void cEquivHandler::sortEquivalents(tChannelID channelID, cSchedules* Schedules)
+{
+ multimap<string, string>::iterator it;
+ pair < multimap < string, string > ::iterator, multimap < string, string
+ > ::iterator > ret;
+ LogD(2, prep("sortEquivalents for channel %s count: %d"), *channelID.ToString(), cEquivHandler::getEquiChanMap().count(*channelID.ToString()));
+
+ ret = equiChanMap.equal_range(*channelID.ToString());
+ for (it = ret.first; it != ret.second; ++it)
+ {
+ LogD(3, prep("equivalent channel exists"));
+ tChannelID equChannelID(tChannelID::FromString((*it).second.c_str()));
+ cChannel* pChannel = GetChannelByID(equChannelID, false);
+ if (pChannel)
+ {
+ LogD(2, prep("found Equivalent channel %s"), *equChannelID.ToString());
+ cSchedule* pSchedule = (cSchedule *) Schedules->GetSchedule(pChannel, true);
+
+ pSchedule->Sort();
+ Schedules->SetModified(pSchedule);
+ }
+ }
+}
diff --git a/equivhandler.h b/equivhandler.h
new file mode 100644
index 0000000..7e7cad7
--- /dev/null
+++ b/equivhandler.h
@@ -0,0 +1,39 @@
+/*
+ * equivhandler.h
+ *
+ * Created on: 19.5.2012
+ * Author: d.petrovski
+ */
+
+#ifndef EQUIVHANDLER_H_
+#define EQUIVHANDLER_H_
+
+#include <vdr/epg.h>
+#include <vdr/channels.h>
+#include <map>
+#include <string>
+
+#define EEPG_FILE_EQUIV "eepg.equiv"
+
+using namespace std;
+
+class cEquivHandler
+{
+public:
+ cEquivHandler();
+ virtual ~cEquivHandler();
+
+ void loadEquivalentChannelMap (void);
+ void updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent);
+ void updateEquivalent(tChannelID channelID, cEvent *pEvent);
+ void sortEquivalents(tChannelID channelID, cSchedules* Schedules);
+
+ static multimap<string, string> getEquiChanMap() { return cEquivHandler::equiChanMap; };
+
+private:
+ static multimap<string, string> equiChanMap;
+ static long equiChanFileTime;
+
+};
+
+#endif /* EQUIVHANDLER_H_ */
diff --git a/setupeepg.c b/setupeepg.c
index 3738227..54f8243 100644
--- a/setupeepg.c
+++ b/setupeepg.c
@@ -23,14 +23,13 @@ cSetupEEPG::cSetupEEPG (void)
#ifdef DEBUG
LogLevel = 0;
#endif
-
}
cSetupEEPG* cSetupEEPG::getInstance()
{
- if (!_setupEEPG)
- _setupEEPG = new cSetupEEPG();
+ if (!_setupEEPG)
+ _setupEEPG = new cSetupEEPG();
- return _setupEEPG;
+ return _setupEEPG;
}
diff --git a/setupeepg.h b/setupeepg.h
index f5e342a..4c30ede 100644
--- a/setupeepg.h
+++ b/setupeepg.h
@@ -7,6 +7,7 @@
#ifndef SETUPEEPG_H_
#define SETUPEEPG_H_
+#include <string.h>
class cSetupEEPG
{
@@ -24,12 +25,28 @@ public:
public:
static cSetupEEPG* getInstance();
+ char* getConfDir() const
+ {
+ return ConfDir;
+ }
+
+ void setConfDir(char* confDir)
+ {
+ if (ConfDir)
+ delete ConfDir;
+ ConfDir = new char[strlen(confDir)+1];
+ strcpy(ConfDir, confDir);
+ }
+
private:
cSetupEEPG (void);
cSetupEEPG(cSetupEEPG const&); // copy constructor is private
cSetupEEPG& operator=(cSetupEEPG const&); // assignment operator is private
static cSetupEEPG* _setupEEPG;
+private:
+ char *ConfDir;
+
};
#endif /* SETUPEEPG_H_ */
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..3d92dda
--- /dev/null
+++ b/util.c
@@ -0,0 +1,209 @@
+/*
+ * util.c
+ *
+ * Created on: 23.5.2012
+ * Author: d.petrovski
+ */
+#include "util.h"
+#include <vdr/channels.h>
+#include <vdr/thread.h>
+#include <vdr/epg.h>
+
+namespace util
+{
+
+int AvailableSources[32];
+int NumberOfAvailableSources = 0;
+
+int Yesterday;
+int YesterdayEpoch;
+int YesterdayEpochUTC;
+
+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;
+}
+
+/*
+ * 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);
+}
+
+// --- cAddEventThread ----------------------------------------
+// Taken from VDR EPGFixer Plug-in
+// http://projects.vdr-developer.org/projects/plg-epgfixer
+// by Matti Lehtimaki
+
+class cAddEventListItem : public cListObject
+{
+protected:
+ cEvent *event;
+ tChannelID channelID;
+public:
+ cAddEventListItem(cEvent *Event, tChannelID ChannelID) { event = Event; channelID = ChannelID; }
+ tChannelID GetChannelID() { return channelID; }
+ cEvent *GetEvent() { return event; }
+ ~cAddEventListItem() { }
+};
+
+class cAddEventThread : public cThread
+{
+private:
+ cTimeMs LastHandleEvent;
+ cList<cAddEventListItem> *list;
+ enum { INSERT_TIMEOUT_IN_MS = 10000 };
+protected:
+ virtual void Action(void);
+public:
+ cAddEventThread(void);
+ ~cAddEventThread(void);
+ void AddEvent(cEvent *Event, tChannelID ChannelID);
+};
+
+cAddEventThread::cAddEventThread(void)
+:cThread("cAddEventThread"), LastHandleEvent()
+{
+ list = new cList<cAddEventListItem>;
+}
+
+cAddEventThread::~cAddEventThread(void)
+{
+ LOCK_THREAD;
+ list->cList::Clear();
+ Cancel(3);
+}
+
+void cAddEventThread::Action(void)
+{
+ SetPriority(19);
+ while (Running() && !LastHandleEvent.TimedOut()) {
+ cAddEventListItem *e = NULL;
+ cSchedulesLock SchedulesLock(true, 10);
+ cSchedules *schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock);
+ Lock();
+ while (schedules && (e = list->First()) != NULL) {
+ cSchedule *schedule = (cSchedule *)schedules->GetSchedule(Channels.GetByChannelID(e->GetChannelID()), true);
+ schedule->AddEvent(e->GetEvent());
+ EpgHandlers.SortSchedule(schedule);
+ EpgHandlers.DropOutdated(schedule, e->GetEvent()->StartTime(), e->GetEvent()->EndTime(), e->GetEvent()->TableID(), e->GetEvent()->Version());
+ list->Del(e);
+ }
+ Unlock();
+ cCondWait::SleepMs(10);
+ }
+}
+
+void cAddEventThread::AddEvent(cEvent *Event, tChannelID ChannelID)
+{
+ LOCK_THREAD;
+ list->Add(new cAddEventListItem(Event, ChannelID));
+ LastHandleEvent.Set(INSERT_TIMEOUT_IN_MS);
+}
+
+static cAddEventThread AddEventThread;
+
+// ---
+
+void AddEvent(cEvent *Event, tChannelID ChannelID)
+{
+ AddEventThread.AddEvent(Event, ChannelID);
+ if (!AddEventThread.Active())
+ AddEventThread.Start();
+}
+
+
+}
+
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..230f44c
--- /dev/null
+++ b/util.h
@@ -0,0 +1,32 @@
+/*
+ * util.h
+ *
+ * Created on: 23.5.2012
+ * Author: d.petrovski
+ */
+
+#ifndef UTIL_H_
+#define UTIL_H_
+#include <time.h>
+class cChannel;
+struct tChannelID;
+class cEvent;
+
+namespace util
+{
+extern int AvailableSources[32];
+extern int NumberOfAvailableSources;
+
+extern int Yesterday;
+extern int YesterdayEpoch;
+extern int YesterdayEpochUTC;
+
+void AddEvent(cEvent *event, tChannelID ChannelID);
+
+cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos);
+time_t LocalTime2UTC (time_t t);
+time_t UTC2LocalTime (time_t t);
+void GetLocalTimeOffset (void);
+void CleanString (unsigned char *String);
+}
+#endif /* UTIL_H_ */