vdr  2.4.0
eit.c
Go to the documentation of this file.
1 /*
2  * eit.c: EIT section filter
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * Original version (as used in VDR before 1.3.0) written by
8  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
9  * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
10  *
11  * $Id: eit.c 4.5 2018/03/31 13:40:32 kls Exp $
12  */
13 
14 #include "eit.h"
15 #include <sys/time.h>
16 #include "epg.h"
17 #include "i18n.h"
18 #include "libsi/section.h"
19 #include "libsi/descriptor.h"
20 
21 #define VALID_TIME (31536000 * 2) // two years
22 
23 // --- cEIT ------------------------------------------------------------------
24 
25 class cEIT : public SI::EIT {
26 public:
27  cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const u_char *Data);
28  };
29 
30 cEIT::cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const u_char *Data)
31 :SI::EIT(Data, false)
32 {
33  if (!CheckCRCAndParse())
34  return;
35  int HashId = Tid * getServiceId();
36  cSectionSyncerEntry *SectionSyncerEntry = SectionSyncerHash.Get(HashId);
37  if (!SectionSyncerEntry) {
38  SectionSyncerEntry = new cSectionSyncerEntry;
39  SectionSyncerHash.Add(SectionSyncerEntry, HashId);
40  }
41  bool Process = SectionSyncerEntry->Sync(getVersionNumber(), getSectionNumber(), getLastSectionNumber());
42  if (Tid != 0x4E && !Process) // we need to set the 'seen' tag to watch the running status of the present/following event
43  return;
44 
45  time_t Now = time(NULL);
46  if (Now < VALID_TIME)
47  return; // we need the current time for handling PDC descriptors
48 
49  cStateKey ChannelsStateKey;
50  cChannels *Channels = cChannels::GetChannelsWrite(ChannelsStateKey, 10);
51  if (!Channels) {
52  SectionSyncerEntry->Repeat(); // let's not miss any section of the EIT
53  return;
54  }
56  cChannel *Channel = Channels->GetByChannelID(channelID, true);
57  if (!Channel || EpgHandlers.IgnoreChannel(Channel)) {
58  ChannelsStateKey.Remove(false);
59  return;
60  }
61 
62  cStateKey SchedulesStateKey;
63  cSchedules *Schedules = cSchedules::GetSchedulesWrite(SchedulesStateKey, 10);
64  if (!Schedules) {
65  SectionSyncerEntry->Repeat(); // let's not miss any section of the EIT
66  ChannelsStateKey.Remove(false);
67  return;
68  }
69 
70  if (!EpgHandlers.BeginSegmentTransfer(Channel)) {
71  SchedulesStateKey.Remove(false);
72  ChannelsStateKey.Remove(false);
73  return;
74  }
75 
76  bool ChannelsModified = false;
77  bool handledExternally = EpgHandlers.HandledExternally(Channel);
78  cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(Channel, true);
79 
80  bool Empty = true;
81  bool Modified = false;
82  time_t LingerLimit = Now - Setup.EPGLinger * 60;
83  time_t SegmentStart = 0;
84  time_t SegmentEnd = 0;
85  struct tm t = { 0 };
86  localtime_r(&Now, &t); // this initializes the time zone in 't'
87 
88  SI::EIT::Event SiEitEvent;
89  for (SI::Loop::Iterator it; eventLoop.getNext(SiEitEvent, it); ) {
90  if (EpgHandlers.HandleEitEvent(pSchedule, &SiEitEvent, Tid, getVersionNumber()))
91  continue; // an EPG handler has done all of the processing
92  time_t StartTime = SiEitEvent.getStartTime();
93  int Duration = SiEitEvent.getDuration();
94  // 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.
95  if (StartTime == 0 || StartTime > 0 && Duration == 0)
96  continue;
97  Empty = false;
98  // Ignore events that ended before the "EPG linger time":
99  if (StartTime + Duration < LingerLimit)
100  continue;
101  if (!SegmentStart)
102  SegmentStart = StartTime;
103  SegmentEnd = StartTime + Duration;
104  cEvent *newEvent = NULL;
105  cEvent *rEvent = NULL;
106  cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), StartTime);
107  if (!pEvent || handledExternally) {
108  if (handledExternally && !EpgHandlers.IsUpdate(SiEitEvent.getEventId(), StartTime, Tid, getVersionNumber()))
109  continue;
110  // If we don't have that event yet, we create a new one.
111  // Otherwise we copy the information into the existing event anyway, because the data might have changed.
112  pEvent = newEvent = new cEvent(SiEitEvent.getEventId());
113  newEvent->SetStartTime(StartTime);
114  newEvent->SetDuration(Duration);
115  if (!handledExternally)
116  pSchedule->AddEvent(newEvent);
117  }
118  else {
119  // We have found an existing event, either through its event ID or its start time.
120  pEvent->SetSeen();
121  uchar TableID = max(pEvent->TableID(), uchar(0x4E)); // for backwards compatibility, table ids less than 0x4E are treated as if they were "present"
122  // If the new event has a higher table ID, let's skip it.
123  // The lower the table ID, the more "current" the information.
124  if (Tid > TableID)
125  continue;
126  EpgHandlers.SetEventID(pEvent, SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-(
127  EpgHandlers.SetStartTime(pEvent, StartTime);
128  EpgHandlers.SetDuration(pEvent, Duration);
129  }
130  if (pEvent->TableID() > 0x4E) // for backwards compatibility, table ids less than 0x4E are never overwritten
131  pEvent->SetTableID(Tid);
132  if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
133  if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning)
134  pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), Channel);
135  if (!Process)
136  continue;
137  }
138  pEvent->SetVersion(getVersionNumber());
139 
140  int LanguagePreferenceShort = -1;
141  int LanguagePreferenceExt = -1;
142  bool UseExtendedEventDescriptor = false;
143  SI::Descriptor *d;
144  SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
145  SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
146  cLinkChannels *LinkChannels = NULL;
147  cComponents *Components = NULL;
148  for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
149  switch (d->getDescriptorTag()) {
152  if (I18nIsPreferredLanguage(Setup.EPGLanguages, eed->languageCode, LanguagePreferenceExt) || !ExtendedEventDescriptors) {
153  delete ExtendedEventDescriptors;
154  ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
155  UseExtendedEventDescriptor = true;
156  }
157  if (UseExtendedEventDescriptor) {
158  if (ExtendedEventDescriptors->Add(eed))
159  d = NULL; // so that it is not deleted
160  }
161  if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber())
162  UseExtendedEventDescriptor = false;
163  }
164  break;
167  if (I18nIsPreferredLanguage(Setup.EPGLanguages, sed->languageCode, LanguagePreferenceShort) || !ShortEventDescriptor) {
168  delete ShortEventDescriptor;
169  ShortEventDescriptor = sed;
170  d = NULL; // so that it is not deleted
171  }
172  }
173  break;
177  int NumContents = 0;
178  uchar Contents[MaxEventContents] = { 0 };
179  for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3); ) {
180  if (NumContents < MaxEventContents) {
181  Contents[NumContents] = ((Nibble.getContentNibbleLevel1() & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF);
182  NumContents++;
183  }
184  }
185  EpgHandlers.SetContents(pEvent, Contents);
186  }
187  break;
189  int LanguagePreferenceRating = -1;
192  for (SI::Loop::Iterator it3; prd->ratingLoop.getNext(Rating, it3); ) {
193  if (I18nIsPreferredLanguage(Setup.EPGLanguages, Rating.languageCode, LanguagePreferenceRating)) {
194  int ParentalRating = (Rating.getRating() & 0xFF);
195  switch (ParentalRating) {
196  // values defined by the DVB standard (minimum age = rating + 3 years):
197  case 0x01 ... 0x0F: ParentalRating += 3; break;
198  // values defined by broadcaster CSAT (now why didn't they just use 0x07, 0x09 and 0x0D?):
199  case 0x11: ParentalRating = 10; break;
200  case 0x12: ParentalRating = 12; break;
201  case 0x13: ParentalRating = 16; break;
202  default: ParentalRating = 0;
203  }
204  EpgHandlers.SetParentalRating(pEvent, ParentalRating);
205  }
206  }
207  }
208  break;
209  case SI::PDCDescriptorTag: {
211  t.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
212  int month = t.tm_mon;
213  t.tm_mon = pd->getMonth() - 1;
214  t.tm_mday = pd->getDay();
215  t.tm_hour = pd->getHour();
216  t.tm_min = pd->getMinute();
217  t.tm_sec = 0;
218  if (month == 11 && t.tm_mon == 0) // current month is dec, but event is in jan
219  t.tm_year++;
220  else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
221  t.tm_year--;
222  time_t vps = mktime(&t);
223  EpgHandlers.SetVps(pEvent, vps);
224  }
225  break;
228  cSchedule *rSchedule = (cSchedule *)Schedules->GetSchedule(tChannelID(Source, Channel->Nid(), Channel->Tid(), tsed->getReferenceServiceId()));
229  if (!rSchedule)
230  break;
231  rEvent = (cEvent *)rSchedule->GetEvent(tsed->getReferenceEventId());
232  if (!rEvent)
233  break;
234  EpgHandlers.SetTitle(pEvent, rEvent->Title());
235  EpgHandlers.SetShortText(pEvent, rEvent->ShortText());
236  EpgHandlers.SetDescription(pEvent, rEvent->Description());
237  }
238  break;
241  tChannelID linkID(Source, ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId());
242  if (ld->getLinkageType() == SI::LinkageTypePremiere) { // Premiere World
243  bool hit = StartTime <= Now && Now < StartTime + Duration;
244  if (hit) {
245  char linkName[ld->privateData.getLength() + 1];
246  strn0cpy(linkName, (const char *)ld->privateData.getData(), sizeof(linkName));
247  // TODO is there a standard way to determine the character set of this string?
248  cChannel *link = Channels->GetByChannelID(linkID);
249  if (link != Channel) { // only link to other channels, not the same one
250  if (link) {
251  if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3)
252  ChannelsModified |= link->SetName(linkName, "", "");
253  }
254  else if (Setup.UpdateChannels >= 4) {
255  cChannel *Transponder = Channel;
256  if (Channel->Tid() != ld->getTransportStreamId())
257  Transponder = Channels->GetByTransponderID(linkID);
258  link = Channels->NewChannel(Transponder, linkName, "", "", ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId());
259  ChannelsModified = true;
260  //XXX patFilter->Trigger();
261  }
262  if (link) {
263  if (!LinkChannels)
264  LinkChannels = new cLinkChannels;
265  LinkChannels->Add(new cLinkChannel(link));
266  }
267  }
268  else
269  ChannelsModified |= Channel->SetPortalName(linkName);
270  }
271  }
272  }
273  break;
276  uchar Stream = cd->getStreamContent();
277  uchar Type = cd->getComponentType();
278  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
279  if (!Components)
280  Components = new cComponents;
281  char buffer[Utf8BufSize(256)];
282  Components->SetComponent(Components->NumComponents(), Stream, Type, I18nNormalizeLanguageCode(cd->languageCode), cd->description.getText(buffer, sizeof(buffer)));
283  }
284  }
285  break;
286  default: ;
287  }
288  delete d;
289  }
290 
291  if (!rEvent) {
292  if (ShortEventDescriptor) {
293  char buffer[Utf8BufSize(256)];
294  EpgHandlers.SetTitle(pEvent, ShortEventDescriptor->name.getText(buffer, sizeof(buffer)));
295  EpgHandlers.SetShortText(pEvent, ShortEventDescriptor->text.getText(buffer, sizeof(buffer)));
296  }
297  else {
298  EpgHandlers.SetTitle(pEvent, NULL);
299  EpgHandlers.SetShortText(pEvent, NULL);
300  }
301  if (ExtendedEventDescriptors) {
302  char buffer[Utf8BufSize(ExtendedEventDescriptors->getMaximumTextLength(": ")) + 1];
303  EpgHandlers.SetDescription(pEvent, ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": "));
304  }
305  else
306  EpgHandlers.SetDescription(pEvent, NULL);
307  }
308  delete ExtendedEventDescriptors;
309  delete ShortEventDescriptor;
310 
311  EpgHandlers.SetComponents(pEvent, Components);
312 
313  EpgHandlers.FixEpgBugs(pEvent);
314  if (LinkChannels)
315  ChannelsModified |= Channel->SetLinkChannels(LinkChannels);
316  Modified = true;
317  EpgHandlers.HandleEvent(pEvent);
318  if (handledExternally)
319  delete pEvent;
320  }
321  if (Tid == 0x4E) {
322  if (Empty && getSectionNumber() == 0)
323  // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running
324  pSchedule->ClrRunningStatus(Channel);
325  pSchedule->SetPresentSeen();
326  }
327  if (Modified) {
328  EpgHandlers.SortSchedule(pSchedule);
329  EpgHandlers.DropOutdated(pSchedule, SegmentStart, SegmentEnd, Tid, getVersionNumber());
330  pSchedule->SetModified();
331  }
332  SchedulesStateKey.Remove(Modified);
333  ChannelsStateKey.Remove(ChannelsModified);
335 }
336 
337 // --- cTDT ------------------------------------------------------------------
338 
339 #define MAX_TIME_DIFF 1 // number of seconds the local time may differ from dvb time before making any corrections
340 #define MAX_ADJ_DIFF 10 // number of seconds the local time may differ from dvb time to allow smooth adjustment
341 #define ADJ_DELTA 300 // number of seconds between calls for smooth time adjustment
342 
343 class cTDT : public SI::TDT {
344 private:
345  static cMutex mutex;
346  static time_t lastAdj;
347 public:
348  cTDT(const u_char *Data);
349  };
350 
352 time_t cTDT::lastAdj = 0;
353 
354 cTDT::cTDT(const u_char *Data)
355 :SI::TDT(Data, false)
356 {
357  CheckParse();
358 
359  time_t dvbtim = getTime();
360  time_t loctim = time(NULL);
361 
362  int diff = dvbtim - loctim;
363  if (abs(diff) > MAX_TIME_DIFF) {
364  mutex.Lock();
365  if (abs(diff) > MAX_ADJ_DIFF) {
366  if (stime(&dvbtim) == 0)
367  isyslog("system time changed from %s (%ld) to %s (%ld)", *TimeToString(loctim), loctim, *TimeToString(dvbtim), dvbtim);
368  else
369  esyslog("ERROR while setting system time: %m");
370  }
371  else if (time(NULL) - lastAdj > ADJ_DELTA) {
372  lastAdj = time(NULL);
373  timeval delta;
374  delta.tv_sec = diff;
375  delta.tv_usec = 0;
376  if (adjtime(&delta, NULL) == 0)
377  isyslog("system time adjustment initiated from %s (%ld) to %s (%ld)", *TimeToString(loctim), loctim, *TimeToString(dvbtim), dvbtim);
378  else
379  esyslog("ERROR while adjusting system time: %m");
380  }
381  mutex.Unlock();
382  }
383 }
384 
385 // --- cEitFilter ------------------------------------------------------------
386 
387 time_t cEitFilter::disableUntil = 0;
388 
390 {
391 //Set(0x12, 0x40, 0xC0); // event info now&next actual/other TS (0x4E/0x4F), future actual/other TS (0x5X/0x6X) // TODO: remove later
392  Set(0x12, 0x40, 0xE0); // event info now&next actual/other TS (0x4E/0x4F), future actual TS (0x5X)
393  Set(0x14, 0x70); // TDT
394 }
395 
397 {
398  cMutexLock MutexLock(&mutex);
399  cFilter::SetStatus(On);
401 }
402 
404 {
405  disableUntil = Time;
406 }
407 
408 void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
409 {
410  cMutexLock MutexLock(&mutex);
411  if (disableUntil) {
412  if (time(NULL) > disableUntil)
413  disableUntil = 0;
414  else
415  return;
416  }
417  switch (Pid) {
418  case 0x12: {
419  //if (Tid >= 0x4E && Tid <= 0x6F) // TODO: remove later
420  if (Tid == 0x4E || Tid >= 0x50 && Tid <= 0x5F)
421  cEIT EIT(sectionSyncerHash, Source(), Tid, Data);
422  }
423  break;
424  case 0x14: {
426  cTDT TDT(Data);
427  }
428  break;
429  default: ;
430  }
431 }
int getOriginalNetworkId() const
Definition: section.c:168
const cChannel * GetByChannelID(tChannelID ChannelID, bool TryWithoutRid=false, bool TryWithoutPolarization=false) const
Definition: channels.c:985
unsigned char uchar
Definition: tools.h:31
bool SetName(const char *Name, const char *ShortName, const char *Provider)
Definition: channels.c:257
Definition: epg.h:71
int getEventId() const
Definition: section.c:205
void Lock(void)
Definition: thread.c:222
void SetContents(cEvent *Event, uchar *Contents)
Definition: epg.c:1458
StructureLoop< Nibble > nibbleLoop
Definition: descriptor.h:102
StructureLoop< Rating > ratingLoop
Definition: descriptor.h:119
bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version)
Definition: epg.c:1395
int getVersionNumber() const
Definition: si.c:84
bool SetPortalName(const char *PortalName)
Definition: channels.c:285
void SetComponent(int Index, const char *s)
Definition: epg.c:77
char * getText()
Definition: si.c:222
cEpgHandlers EpgHandlers
Definition: epg.c:1384
int getOriginalNetworkId() const
Definition: descriptor.c:763
void SetDescription(cEvent *Event, const char *Description)
Definition: epg.c:1449
void SetStartTime(time_t StartTime)
Definition: epg.c:216
void SetDuration(int Duration)
Definition: epg.c:227
StructureLoop< Event > eventLoop
Definition: section.h:182
int getMinute() const
Definition: descriptor.c:831
void Clear(void)
Definition: tools.c:2372
void SetTableID(uchar TableID)
Definition: epg.c:167
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2152
int getHour() const
Definition: descriptor.c:827
int NumComponents(void) const
Definition: epg.h:59
Definition: eit.c:25
time_t getStartTime() const
Definition: section.c:197
static void SetDisableUntil(time_t Time)
Definition: eit.c:403
void DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version)
Definition: epg.c:1538
void SetParentalRating(cEvent *Event, int ParentalRating)
Definition: epg.c:1467
int getContentNibbleLevel1() const
Definition: descriptor.c:284
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
Definition: thread.c:859
#define esyslog(a...)
Definition: tools.h:35
void SetTitle(cEvent *Event, const char *Title)
Definition: epg.c:1431
void SetEventID(cEvent *Event, tEventID EventID)
Definition: epg.c:1422
char * strn0cpy(char *dest, const char *src, size_t n)
Definition: tools.c:131
#define ADJ_DELTA
Definition: eit.c:341
int EPGLanguages[I18N_MAX_LANGUAGES+1]
Definition: config.h:291
T max(T a, T b)
Definition: tools.h:60
int Nid(void) const
Definition: channels.h:172
int EPGLinger
Definition: config.h:294
time_t getTime() const
Definition: section.c:254
#define MAX_ADJ_DIFF
Definition: eit.c:340
bool HandledExternally(const cChannel *Channel)
Definition: epg.c:1404
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: eit.c:396
bool BeginSegmentTransfer(const cChannel *Channel)
Definition: epg.c:1547
int getLength() const
Definition: util.h:58
void SetSeen(void)
Definition: epg.c:237
void ClrRunningStatus(cChannel *Channel=NULL)
Definition: epg.c:1035
int TimeTransponder
Definition: config.h:283
Definition: descriptor.c:16
void HandleEvent(cEvent *Event)
Definition: epg.c:1521
static cChannels * GetChannelsWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of channels for write access.
Definition: channels.c:854
cString TimeToString(time_t t)
Converts the given time to a string of the form "www mmm dd hh:mm:ss yyyy".
Definition: tools.c:1203
void SetStartTime(cEvent *Event, time_t StartTime)
Definition: epg.c:1476
#define VALID_TIME
Definition: eit.c:21
bool Sync(uchar Version, int Number, int LastNumber)
Definition: filter.c:36
Definition: eit.c:343
void CheckParse()
Definition: util.c:182
cChannel * NewChannel(const cChannel *Transponder, const char *Name, const char *ShortName, const char *Provider, int Nid, int Tid, int Sid, int Rid=0)
Definition: channels.c:1080
static cMutex mutex
Definition: eit.c:345
#define ISTRANSPONDER(f1, f2)
Definition: channels.h:18
int getServiceId() const
Definition: descriptor.c:767
int getContentNibbleLevel2() const
Definition: descriptor.c:288
int Source(void)
Returns the source of the data delivered to this filter.
Definition: filter.c:114
cMutex mutex
Definition: eit.h:25
void SetDuration(cEvent *Event, int Duration)
Definition: epg.c:1485
const char * ShortText(void) const
Definition: epg.h:104
bool Add(GroupDescriptor *d)
Definition: si.c:201
static time_t disableUntil
Definition: eit.h:27
int TimeSource
Definition: config.h:282
cSetup Setup
Definition: config.c:372
time_t getDuration() const
Definition: section.c:201
void FixEpgBugs(cEvent *Event)
Definition: epg.c:1512
#define MAX_TIME_DIFF
Definition: eit.c:339
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
Processes the data delivered to this filter.
Definition: eit.c:408
const cSchedule * GetSchedule(tChannelID ChannelID) const
Definition: epg.c:1331
void Repeat(void)
Definition: filter.c:29
const cEvent * GetEvent(tEventID EventID, time_t StartTime=0) const
Definition: epg.c:993
void SortSchedule(cSchedule *Schedule)
Definition: epg.c:1529
Definition: thread.h:67
int Tid(void) const
Definition: channels.h:173
cEitFilter(void)
Definition: eit.c:389
void SetPresentSeen(void)
Definition: epg.h:168
cEvent * AddEvent(cEvent *Event)
Definition: epg.c:933
int getMonth() const
Definition: descriptor.c:823
int getSectionNumber() const
Definition: si.c:88
bool CheckCRCAndParse()
Definition: si.c:65
void SetVps(cEvent *Event, time_t Vps)
Definition: epg.c:1494
T * Get(unsigned int Id) const
Definition: tools.h:882
bool IgnoreChannel(const cChannel *Channel)
Definition: epg.c:1386
int SetSystemTime
Definition: config.h:281
bool I18nIsPreferredLanguage(int *PreferredLanguages, const char *LanguageCode, int &OldPreference, int *Position)
Checks the given LanguageCode (which may be something like "eng" or "eng+deu") against the PreferredL...
Definition: i18n.c:269
const char * Title(void) const
Definition: epg.h:103
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: filter.c:129
static cSchedules * GetSchedulesWrite(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of schedules for write access.
Definition: epg.c:1236
const unsigned char * getData() const
Definition: util.h:51
cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const u_char *Data)
Definition: eit.c:30
int getStreamContent() const
Definition: descriptor.c:562
Definition: epg.h:150
unsigned char u_char
Definition: headers.h:24
int UpdateChannels
Definition: config.h:319
bool SetLinkChannels(cLinkChannels *LinkChannels)
Definition: channels.c:486
#define isyslog(a...)
Definition: tools.h:36
static time_t lastAdj
Definition: eit.c:346
int getTransportStreamId() const
Definition: section.c:164
void SetVersion(uchar Version)
Definition: epg.c:172
cSectionSyncerHash sectionSyncerHash
Definition: eit.h:26
void SetModified(void)
Definition: epg.h:167
void Add(cListObject *Object, unsigned int Id)
Definition: tools.c:2351
DescriptorTag getDescriptorTag() const
Definition: si.c:100
int Transponder(void)
Returns the transponder of the data delivered to this filter.
Definition: filter.c:119
void Set(u_short Pid, u_char Tid, u_char Mask=0xFF)
Sets the given filter data by calling Add() with Sticky = true.
Definition: filter.c:162
char * getText(const char *separation1="\t", const char *separation2="\n")
Definition: descriptor.c:86
LinkageType getLinkageType() const
Definition: descriptor.c:771
int getTransportStreamId() const
Definition: descriptor.c:759
void SetComponents(cEvent *Event, cComponents *Components)
Definition: epg.c:1503
int getComponentType() const
Definition: descriptor.c:566
void SetShortText(cEvent *Event, const char *ShortText)
Definition: epg.c:1440
void SetRunningStatus(cEvent *Event, int RunningStatus, const cChannel *Channel=NULL)
Definition: epg.c:1017
uchar TableID(void) const
Definition: epg.h:100
bool IsUpdate(tEventID EventID, time_t StartTime, uchar TableID, uchar Version)
Definition: epg.c:1413
const cChannel * GetByTransponderID(tChannelID ChannelID) const
Definition: channels.c:1015
const char * I18nNormalizeLanguageCode(const char *Code)
Returns a 3 letter language code that may not be zero terminated.
Definition: i18n.c:238
cTDT(const u_char *Data)
Definition: eit.c:354
void EndSegmentTransfer(bool Modified)
Definition: epg.c:1556
DescriptorLoop eventDescriptors
Definition: section.h:170
Descriptor * getNext(Iterator &it)
Definition: si.c:112
RunningStatus getRunningStatus() const
Definition: section.c:237
int getServiceId() const
Definition: section.c:160
int getDay() const
Definition: descriptor.c:819
int getLastSectionNumber() const
Definition: si.c:92
#define Utf8BufSize(s)
Definition: tools.h:141
int getMaximumTextLength(const char *separation1="\t", const char *separation2="\n")
Definition: descriptor.c:81
void Unlock(void)
Definition: thread.c:228
const char * Description(void) const
Definition: epg.h:105