void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) { switch (Pid) { case 0x12: { cSchedulesLock SchedulesLock(true, 10); cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); if (Schedules) cEIT EIT(Schedules, Source(), Tid, Data); else { // 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(false, 50); cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); if (Schedules) cEIT EIT(Schedules, Source(), Tid, Data, true); } } break; case 0x14: { if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder)) cTDT TDT(Data); } break; } }
void cSchedules::Cleanup(bool Force) { if (Force) lastDump = 0; time_t now = time(NULL); struct tm tm_r; struct tm *ptm = localtime_r(&now, &tm_r); if (now - lastCleanup > 3600) { isyslog("cleaning up schedules data"); cSchedulesLock SchedulesLock(true, 1000); cSchedules *s = (cSchedules *)Schedules(SchedulesLock); if (s) { for (cSchedule *p = s->First(); p; p = s->Next(p)) p->Cleanup(now); } lastCleanup = now; if (ptm->tm_hour == 5) ReportEpgBugFixStats(true); } if (epgDataFileName && now - lastDump > 600) { cSafeFile f(epgDataFileName); if (f.Open()) { Dump(f); f.Close(); } else LOG_ERROR; lastDump = now; } }
bool cSchedules::Read(FILE *f) { cSchedulesLock SchedulesLock(true, 1000); cSchedules *s = (cSchedules *)Schedules(SchedulesLock); if (s) { bool OwnFile = f == NULL; if (OwnFile) { if (epgDataFileName && access(epgDataFileName, R_OK) == 0) { dsyslog("reading EPG data from %s", epgDataFileName); if ((f = fopen(epgDataFileName, "r")) == NULL) { LOG_ERROR; return false; } } else return false; } bool result = cSchedule::Read(f, s); if (OwnFile) fclose(f); if (result) { // Initialize the channels' schedule pointers, so that the first WhatsOn menu will come up faster: for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) s->GetSchedule(Channel); } return result; } return false; }
void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) { switch (Pid) { case 0x12: { cSchedulesLock SchedulesLock(true, 10); cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); if (Schedules) cEIT EIT(Schedules, Source(), Tid, Data); else { // 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) cEIT EIT(Schedules, Source(), Tid, Data, true); } } break; case 0x14: { /* TB: (time(NULL) < 31536000*2) * always get the time if the system time has never been set * regardless of the transponder */ if ((time(NULL) < VALID_TIME) || ((Setup.SetSystemTime && Setup.TimeTransponder) && ISTRANSPONDER(Transponder(), Setup.TimeTransponder))) cTDT TDT(Data); } break; } }
void cSchedules::ResetVersions(void) { cSchedulesLock SchedulesLock(true); cSchedules *s = (cSchedules *)Schedules(SchedulesLock); if (s) { for (cSchedule *Schedule = s->First(); Schedule; Schedule = s->Next(Schedule)) Schedule->ResetVersions(); } }
bool cSchedules::ClearAll(void) { cSchedulesLock SchedulesLock(true, 1000); cSchedules *s = (cSchedules *)Schedules(SchedulesLock); if (s) { for (cTimer *Timer = Timers.First(); Timer; Timer = Timers.Next(Timer)) Timer->SetEvent(NULL); for (cSchedule *Schedule = s->First(); Schedule; Schedule = s->Next(Schedule)) Schedule->Cleanup(INT_MAX); return true; } return false; }
void cEpgDataWriter::Perform(void) { cMutexLock MutexLock(&mutex); // to make sure fore- and background calls don't cause parellel dumps! { cSchedulesLock SchedulesLock(true, 1000); cSchedules *s = (cSchedules *)cSchedules::Schedules(SchedulesLock); if (s) { time_t now = time(NULL); for (cSchedule *p = s->First(); p; p = s->Next(p)) p->Cleanup(now); } } cSchedules::Dump(); }
static void ClearEPG(cDBusObject *Object, GVariant *Parameters, GDBusMethodInvocation *Invocation) { const char *channel = NULL; int timeout = 0; g_variant_get(Parameters, "(&si)", &channel, &timeout); int eitDisableTime = 10; // seconds until EIT processing is enabled again after a CLRE command if (timeout > 0) { eitDisableTime = timeout; isyslog("dbus2vdr: %s.ClearEPG: using %d seconds as EIT disable timeout", DBUS_VDR_EPG_INTERFACE, eitDisableTime); } if (channel) { tChannelID ChannelID = tChannelID::InvalidID; if (isnumber(channel)) { int o = strtol(channel, NULL, 10); #if VDRVERSNUM > 20300 LOCK_CHANNELS_READ; const cChannels *channels = Channels; #else cChannels *channels = &Channels; #endif if (o >= 1 && o <= channels->MaxNumber()) ChannelID = channels->GetByNumber(o)->GetChannelID(); } else { ChannelID = tChannelID::FromString(channel); if (ChannelID == tChannelID::InvalidID) { const cChannels *channels = NULL; #if VDRVERSNUM > 20300 LOCK_CHANNELS_READ; channels = Channels; #else channels = &Channels; #endif for (const cChannel *Channel = channels->First(); Channel; Channel = channels->Next(Channel)) { if (!Channel->GroupSep()) { if (strcasecmp(Channel->Name(), channel) == 0) { ChannelID = Channel->GetChannelID(); break; } } } } } if (!(ChannelID == tChannelID::InvalidID)) { #if VDRVERSNUM > 20300 cStateKey StateKey; cSchedules *s = cSchedules::GetSchedulesWrite(StateKey, 1000); #else cSchedulesLock SchedulesLock(true, 1000); cSchedules *s = (cSchedules *)cSchedules::Schedules(SchedulesLock); #endif if (s) { cSchedule *Schedule = NULL; ChannelID.ClrRid(); for (cSchedule *p = s->First(); p; p = s->Next(p)) { if (p->ChannelID() == ChannelID) { Schedule = p; break; } } if (Schedule) { Schedule->Cleanup(INT_MAX); #if APIVERSNUM >= 10711 cEitFilter::SetDisableUntil(time(NULL) + eitDisableTime); #endif cString replyMessage = cString::sprintf("EPG data of channel \"%s\" cleared", channel); cDBusHelper::SendReply(Invocation, 250, *replyMessage); } else { cString replyMessage = cString::sprintf("No EPG data found for channel \"%s\"", channel); cDBusHelper::SendReply(Invocation, 550, *replyMessage); } #if VDRVERSNUM > 20300 StateKey.Remove(); #endif } else cDBusHelper::SendReply(Invocation, 451, "Can't get EPG data"); } else { cString replyMessage = cString::sprintf("Undefined channel \"%s\"", channel); cDBusHelper::SendReply(Invocation, 501, *replyMessage); } } else { #if VDRVERSNUM > 20300 LOCK_TIMERS_WRITE; LOCK_SCHEDULES_WRITE; for (cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) Timer->SetEvent(NULL); // processing all timers here (local *and* remote) for (cSchedule *Schedule = Schedules->First(); Schedule; Schedule = Schedules->Next(Schedule)) Schedule->Cleanup(INT_MAX); #else cSchedules::ClearAll(); #endif cEitFilter::SetDisableUntil(time(NULL) + eitDisableTime); cDBusHelper::SendReply(Invocation, 250, "EPG data cleared"); } };