1 #include <lib/dvb/epgcache.h>
2 #include <lib/dvb/dvb.h>
7 #include <unistd.h> // for usleep
8 #include <sys/vfs.h> // for statfs
9 // #include <libmd5sum.h>
10 #include <lib/base/eerror.h>
12 int eventData::CacheSize=0;
13 descriptorMap eventData::descriptors;
15 extern const uint32_t crc32_table[256];
17 eventData::eventData(const eit_event_struct* e, int size, int type)
18 :ByteSize(size), type(type)
23 __u8 *data = (__u8*)e;
25 int descriptors_length = (data[ptr++]&0x0F) << 8;
26 descriptors_length |= data[ptr++];
27 while ( descriptors_length > 0 )
29 int descr_len = data[ptr+1] + 2;
30 __u8 *descr = new __u8[descr_len];
33 while(cnt < descr_len && descriptors_length > 0)
35 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ data[ptr]) & 0xff];
36 descr[cnt++] = data[ptr++];
39 descriptorMap::iterator it =
40 descriptors.find(crc);
41 if ( it == descriptors.end() )
44 descriptors[crc] = descriptorPair(1, descr);
53 ByteSize = 12+d.size()*4;
54 EITdata = new __u8[ByteSize];
56 memcpy(EITdata, (__u8*) e, 12);
57 __u32 *p = (__u32*)(EITdata+12);
58 for (std::list<__u32>::iterator it(d.begin()); it != d.end(); ++it)
62 const eit_event_struct* eventData::get() const
64 static __u8 *data=NULL;
72 int tmp = ByteSize-12;
73 __u32 *p = (__u32*)(EITdata+12);
76 descriptorMap::iterator it =
77 descriptors.find(*p++);
78 if ( it != descriptors.end() )
80 d.push_back(it->second.second);
81 bytes += it->second.second[1];
83 bytes += 2; // descr_type, descr_len
87 // copy eit_event header to buffer
88 data = new __u8[bytes];
89 memcpy(data, EITdata, 12);
92 // copy all descriptors to buffer
93 for(std::list<__u8*>::iterator it(d.begin()); it != d.end(); ++it)
96 memcpy(data+tmp, *it, b);
100 return (eit_event_struct*)data;
103 eventData::~eventData()
109 __u32 *d = (__u32*)(EITdata+12);
112 descriptorMap::iterator it =
113 descriptors.find(*d++);
114 if ( it != descriptors.end() )
116 descriptorPair &p = it->second;
117 if (!--p.first) // no more used descriptor
119 CacheSize -= p.second[1]+2;
120 delete [] p.second; // free descriptor memory
121 descriptors.erase(it); // remove entry from descriptor map
130 void eventData::load(FILE *f)
136 fread(&size, sizeof(int), 1, f);
139 fread(&id, sizeof(__u32), 1, f);
140 fread(&p.first, sizeof(int), 1, f);
141 fread(header, 2, 1, f);
142 int bytes = header[1]+2;
143 p.second = new __u8[bytes];
144 p.second[0] = header[0];
145 p.second[1] = header[1];
146 fread(p.second+2, bytes-2, 1, f);
153 void eventData::save(FILE *f)
155 int size=descriptors.size();
156 descriptorMap::iterator it(descriptors.begin());
157 fwrite(&size, sizeof(int), 1, f);
160 fwrite(&it->first, sizeof(__u32), 1, f);
161 fwrite(&it->second.first, sizeof(int), 1, f);
162 fwrite(it->second.second, it->second.second[1]+2, 1, f);
168 eEPGCache* eEPGCache::instance;
169 pthread_mutex_t eEPGCache::cache_lock=
170 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
171 pthread_mutex_t eEPGCache::channel_map_lock=
172 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
174 DEFINE_REF(eEPGCache)
176 eEPGCache::eEPGCache()
177 :messages(this,1), cleanTimer(this)//, paused(0)
179 eDebug("[EPGC] Initialized EPGCache");
181 CONNECT(messages.recv_msg, eEPGCache::gotMessage);
182 CONNECT(eDVBLocalTimeHandler::getInstance()->m_timeUpdated, eEPGCache::timeUpdated);
183 CONNECT(cleanTimer.timeout, eEPGCache::cleanLoop);
185 ePtr<eDVBResourceManager> res_mgr;
186 eDVBResourceManager::getInstance(res_mgr);
188 eDebug("[eEPGCache] no resource manager !!!!!!!");
190 res_mgr->connectChannelAdded(slot(*this,&eEPGCache::DVBChannelAdded), m_chanAddedConn);
194 void eEPGCache::timeUpdated()
196 if ( !thread_running() )
198 eDebug("[EPGC] time updated.. start EPG Mainloop");
202 messages.send(Message(Message::timeChanged));
205 void eEPGCache::DVBChannelAdded(eDVBChannel *chan)
209 eDebug("[eEPGCache] add channel %p", chan);
210 channel_data *data = new channel_data(this);
211 data->channel = chan;
212 singleLock s(channel_map_lock);
213 m_knownChannels.insert( std::pair<iDVBChannel*, channel_data* >(chan, data) );
214 chan->connectStateChange(slot(*this, &eEPGCache::DVBChannelStateChanged), data->m_stateChangedConn);
218 void eEPGCache::DVBChannelRunning(iDVBChannel *chan)
220 singleLock s(channel_map_lock);
221 channelMapIterator it =
222 m_knownChannels.find(chan);
223 if ( it == m_knownChannels.end() )
224 eDebug("[eEPGCache] will start non existing channel %p !!!", chan);
227 channel_data &data = *it->second;
228 ePtr<eDVBResourceManager> res_mgr;
229 if ( eDVBResourceManager::getInstance( res_mgr ) )
230 eDebug("[eEPGCache] no res manager!!");
233 ePtr<iDVBDemux> demux;
234 if ( data.channel->getDemux(demux) )
236 eDebug("[eEPGCache] no demux!!");
241 RESULT res = demux->createSectionReader( this, data.m_NowNextReader );
244 eDebug("[eEPGCache] couldnt initialize nownext reader!!");
247 data.m_NowNextReader->connectRead(slot(data, &eEPGCache::channel_data::readData), data.m_NowNextConn);
248 res = demux->createSectionReader( this, data.m_ScheduleReader );
251 eDebug("[eEPGCache] couldnt initialize schedule reader!!");
254 data.m_ScheduleReader->connectRead(slot(data, &eEPGCache::channel_data::readData), data.m_ScheduleConn);
255 res = demux->createSectionReader( this, data.m_ScheduleOtherReader );
258 eDebug("[eEPGCache] couldnt initialize schedule other reader!!");
261 data.m_ScheduleOtherReader->connectRead(slot(data, &eEPGCache::channel_data::readData), data.m_ScheduleOtherConn);
262 messages.send(Message(Message::startChannel, chan));
263 // -> gotMessage -> changedService
269 void eEPGCache::DVBChannelStateChanged(iDVBChannel *chan)
271 channelMapIterator it =
272 m_knownChannels.find(chan);
273 if ( it != m_knownChannels.end() )
276 chan->getState(state);
279 case iDVBChannel::state_idle:
281 case iDVBChannel::state_tuning:
283 case iDVBChannel::state_unavailable:
285 case iDVBChannel::state_ok:
287 eDebug("[eEPGCache] channel %p running", chan);
288 DVBChannelRunning(chan);
291 case iDVBChannel::state_release:
293 eDebug("[eEPGCache] remove channel %p", chan);
294 messages.send(Message(Message::leaveChannel, chan));
295 while(!it->second->can_delete)
298 m_knownChannels.erase(it);
299 // -> gotMessage -> abortEPG
306 void eEPGCache::sectionRead(const __u8 *data, int source, channel_data *channel)
308 eit_t *eit = (eit_t*) data;
310 int len=HILO(eit->section_length)-1;//+3-4;
315 // This fixed the EPG on the Multichoice irdeto systems
316 // the EIT packet is non-compliant.. their EIT packet stinks
317 if ( data[ptr-1] < 0x40 )
320 uniqueEPGKey service( HILO(eit->service_id), HILO(eit->original_network_id), HILO(eit->transport_stream_id) );
321 eit_event_struct* eit_event = (eit_event_struct*) (data+ptr);
325 time_t TM = parseDVBtime( eit_event->start_time_1, eit_event->start_time_2, eit_event->start_time_3, eit_event->start_time_4, eit_event->start_time_5);
326 time_t now = time(0)+eDVBLocalTimeHandler::getInstance()->difference();
328 if ( TM != 3599 && TM > -1)
329 channel->haveData |= source;
331 singleLock s(cache_lock);
332 // hier wird immer eine eventMap zurück gegeben.. entweder eine vorhandene..
333 // oder eine durch [] erzeugte
334 std::pair<eventMap,timeMap> &servicemap = eventDB[service];
335 eventMap::iterator prevEventIt = servicemap.first.end();
336 timeMap::iterator prevTimeIt = servicemap.second.end();
340 eit_event_size = HILO(eit_event->descriptors_loop_length)+EIT_LOOP_SIZE;
342 duration = fromBCD(eit_event->duration_1)*3600+fromBCD(eit_event->duration_2)*60+fromBCD(eit_event->duration_3);
344 eit_event->start_time_1,
345 eit_event->start_time_2,
346 eit_event->start_time_3,
347 eit_event->start_time_4,
348 eit_event->start_time_5);
353 if ( TM != 3599 && (TM+duration < now || TM > now+14*24*60*60) )
356 if ( now <= (TM+duration) || TM == 3599 /*NVOD Service*/ ) // old events should not be cached
358 __u16 event_id = HILO(eit_event->event_id);
359 // eDebug("event_id is %d sid is %04x", event_id, service.sid);
362 int ev_erase_count = 0;
363 int tm_erase_count = 0;
365 // search in eventmap
366 eventMap::iterator ev_it =
367 servicemap.first.find(event_id);
369 // entry with this event_id is already exist ?
370 if ( ev_it != servicemap.first.end() )
372 if ( source > ev_it->second->type ) // update needed ?
373 goto next; // when not.. the skip this entry
375 // search this event in timemap
376 timeMap::iterator tm_it_tmp =
377 servicemap.second.find(ev_it->second->getStartTime());
379 if ( tm_it_tmp != servicemap.second.end() )
381 if ( tm_it_tmp->first == TM ) // correct eventData
384 delete ev_it->second;
385 evt = new eventData(eit_event, eit_event_size, source);
387 tm_it_tmp->second=evt;
393 // delete the found record from timemap
394 servicemap.second.erase(tm_it_tmp);
395 prevTimeIt=servicemap.second.end();
400 // search in timemap, for check of a case if new time has coincided with time of other event
401 // or event was is not found in eventmap
402 timeMap::iterator tm_it =
403 servicemap.second.find(TM);
405 if ( tm_it != servicemap.second.end() )
407 // i think, if event is not found on eventmap, but found on timemap updating nevertheless demands
409 if ( source > tm_it->second->type && tm_erase_count == 0 ) // update needed ?
410 goto next; // when not.. the skip this entry
413 // search this time in eventmap
414 eventMap::iterator ev_it_tmp =
415 servicemap.first.find(tm_it->second->getEventID());
417 if ( ev_it_tmp != servicemap.first.end() )
420 // delete the found record from eventmap
421 servicemap.first.erase(ev_it_tmp);
422 prevEventIt=servicemap.first.end();
426 evt = new eventData(eit_event, eit_event_size, source);
428 bool consistencyCheck=true;
430 if (ev_erase_count > 0 && tm_erase_count > 0) // 2 different pairs have been removed
433 delete ev_it->second;
434 delete tm_it->second;
438 else if (ev_erase_count == 0 && tm_erase_count > 0)
441 delete ev_it->second;
442 tm_it=prevTimeIt=servicemap.second.insert( prevTimeIt, std::pair<const time_t, eventData*>( TM, evt ) );
445 else if (ev_erase_count > 0 && tm_erase_count == 0)
448 delete tm_it->second;
449 ev_it=prevEventIt=servicemap.first.insert( prevEventIt, std::pair<const __u16, eventData*>( event_id, evt) );
452 else // added new eventData
455 consistencyCheck=false;
457 prevEventIt=servicemap.first.insert( prevEventIt, std::pair<const __u16, eventData*>( event_id, evt) );
458 prevTimeIt=servicemap.second.insert( prevTimeIt, std::pair<const time_t, eventData*>( TM, evt ) );
461 if ( consistencyCheck )
463 if ( tm_it->second != evt || ev_it->second != evt )
464 eFatal("tm_it->second != ev_it->second");
465 else if ( tm_it->second->getStartTime() != tm_it->first )
466 eFatal("event start_time(%d) non equal timemap key(%d)",
467 tm_it->second->getStartTime(), tm_it->first );
468 else if ( tm_it->first != TM )
469 eFatal("timemap key(%d) non equal TM(%d)",
471 else if ( ev_it->second->getEventID() != ev_it->first )
472 eFatal("event_id (%d) non equal event_map key(%d)",
473 ev_it->second->getEventID(), ev_it->first);
474 else if ( ev_it->first != event_id )
475 eFatal("eventmap key(%d) non equal event_id(%d)",
476 ev_it->first, event_id );
482 if ( servicemap.first.size() != servicemap.second.size() )
484 FILE *f = fopen("/hdd/event_map.txt", "w+");
486 for (eventMap::iterator it(servicemap.first.begin())
487 ; it != servicemap.first.end(); ++it )
488 fprintf(f, "%d(key %d) -> time %d, event_id %d, data %p\n",
489 i++, (int)it->first, (int)it->second->getStartTime(), (int)it->second->getEventID(), it->second );
491 f = fopen("/hdd/time_map.txt", "w+");
493 for (timeMap::iterator it(servicemap.second.begin())
494 ; it != servicemap.second.end(); ++it )
495 fprintf(f, "%d(key %d) -> time %d, event_id %d, data %p\n",
496 i++, (int)it->first, (int)it->second->getStartTime(), (int)it->second->getEventID(), it->second );
499 eFatal("(1)map sizes not equal :( sid %04x tsid %04x onid %04x size %d size2 %d",
500 service.sid, service.tsid, service.onid,
501 servicemap.first.size(), servicemap.second.size() );
504 ptr += eit_event_size;
505 eit_event=(eit_event_struct*)(((__u8*)eit_event)+eit_event_size);
509 void eEPGCache::flushEPG(const uniqueEPGKey & s)
511 eDebug("[EPGC] flushEPG %d", (int)(bool)s);
512 singleLock l(cache_lock);
513 if (s) // clear only this service
515 eventCache::iterator it = eventDB.find(s);
516 if ( it != eventDB.end() )
518 eventMap &evMap = it->second.first;
519 timeMap &tmMap = it->second.second;
521 for (eventMap::iterator i = evMap.begin(); i != evMap.end(); ++i)
526 // TODO .. search corresponding channel for removed service and remove this channel from lastupdated map
529 else // clear complete EPG Cache
531 for (eventCache::iterator it(eventDB.begin());
532 it != eventDB.end(); ++it)
534 eventMap &evMap = it->second.first;
535 timeMap &tmMap = it->second.second;
536 for (eventMap::iterator i = evMap.begin(); i != evMap.end(); ++i)
542 channelLastUpdated.clear();
543 singleLock m(channel_map_lock);
544 for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
545 it->second->startEPG();
547 eDebug("[EPGC] %i bytes for cache used", eventData::CacheSize);
550 void eEPGCache::cleanLoop()
552 singleLock s(cache_lock);
553 if (!eventDB.empty())
555 eDebug("[EPGC] start cleanloop");
557 time_t now = time(0)+eDVBLocalTimeHandler::getInstance()->difference();
559 for (eventCache::iterator DBIt = eventDB.begin(); DBIt != eventDB.end(); DBIt++)
561 for (timeMap::iterator It = DBIt->second.second.begin(); It != DBIt->second.second.end() && It->first < now;)
563 if ( now > (It->first+It->second->getDuration()) ) // outdated normal entry (nvod references to)
565 // remove entry from eventMap
566 eventMap::iterator b(DBIt->second.first.find(It->second->getEventID()));
567 if ( b != DBIt->second.first.end() )
569 // release Heap Memory for this entry (new ....)
570 // eDebug("[EPGC] delete old event (evmap)");
571 DBIt->second.first.erase(b);
574 // remove entry from timeMap
575 // eDebug("[EPGC] release heap mem");
577 DBIt->second.second.erase(It++);
578 // eDebug("[EPGC] delete old event (timeMap)");
584 eDebug("[EPGC] stop cleanloop");
585 eDebug("[EPGC] %i bytes for cache used", eventData::CacheSize);
587 cleanTimer.start(CLEAN_INTERVAL,true);
590 eEPGCache::~eEPGCache()
592 messages.send(Message::quit);
593 kill(); // waiting for thread shutdown
594 singleLock s(cache_lock);
595 for (eventCache::iterator evIt = eventDB.begin(); evIt != eventDB.end(); evIt++)
596 for (eventMap::iterator It = evIt->second.first.begin(); It != evIt->second.first.end(); It++)
600 RESULT eEPGCache::lookupEvent(const eServiceReferenceDVB &service, int event_id, const eventData *&result )
602 singleLock s(cache_lock);
603 uniqueEPGKey key( service );
605 eventCache::iterator It = eventDB.find( key );
606 if ( It != eventDB.end() && !It->second.first.empty() ) // entrys cached?
608 eventMap::iterator i( It->second.first.find( event_id ));
609 if ( i != It->second.first.end() )
617 eDebug("event %04x not found in epgcache", event_id);
623 RESULT eEPGCache::lookupEvent(const eServiceReferenceDVB &service, time_t t, const eventData *&result )
624 // if t == 0 we search the current event...
626 singleLock s(cache_lock);
627 uniqueEPGKey key(service);
629 // check if EPG for this service is ready...
630 eventCache::iterator It = eventDB.find( key );
631 if ( It != eventDB.end() && !It->second.first.empty() ) // entrys cached ?
634 t = time(0)+eDVBLocalTimeHandler::getInstance()->difference();
636 timeMap::iterator i = It->second.second.lower_bound(t);
637 if ( i != It->second.second.end() )
640 if ( i != It->second.second.end() )
642 if ( t <= i->first+i->second->getDuration() )
650 for ( eventMap::iterator i( It->second.first.begin() ); i != It->second.first.end(); i++)
652 int duration = i->second->getDuration();
653 time_t begTime = i->second->getStartTime();
654 if ( t >= begTime && t <= begTime+duration) // then we have found
664 void eEPGCache::gotMessage( const Message &msg )
669 flushEPG(msg.service);
671 case Message::startChannel:
673 singleLock s(channel_map_lock);
674 channelMapIterator channel =
675 m_knownChannels.find(msg.channel);
676 if ( channel != m_knownChannels.end() )
677 channel->second->startChannel();
680 case Message::leaveChannel:
682 singleLock s(channel_map_lock);
683 channelMapIterator channel =
684 m_knownChannels.find(msg.channel);
685 if ( channel != m_knownChannels.end() )
686 channel->second->abortEPG();
692 case Message::timeChanged:
696 eDebug("unhandled EPGCache Message!!");
701 void eEPGCache::thread()
710 void eEPGCache::load()
713 FILE *f = fopen("/hdd/epg.dat", "r");
716 unsigned char md5_saved[16];
717 unsigned char md5[16];
721 if (!md5_file("/hdd/epg.dat", 1, md5))
723 FILE *f = fopen("/hdd/epg.dat.md5", "r");
726 fread( md5_saved, 16, 1, f);
728 if ( !memcmp(md5_saved, md5, 16) )
735 fread( text1, 13, 1, f);
736 if ( !strncmp( text1, "ENIGMA_EPG_V2", 13) )
738 fread( &size, sizeof(int), 1, f);
745 fread( &key, sizeof(uniqueEPGKey), 1, f);
746 fread( &size, sizeof(int), 1, f);
752 fread( &type, sizeof(int), 1, f);
753 fread( &len, sizeof(int), 1, f);
754 event = new eventData(0, len, type);
755 event->EITdata = new __u8[len];
756 eventData::CacheSize+=len;
757 fread( event->EITdata, len, 1, f);
758 evMap[ event->getEventID() ]=event;
759 tmMap[ event->getStartTime() ]=event;
762 eventDB[key]=std::pair<eventMap,timeMap>(evMap,tmMap);
765 eDebug("%d events read from /hdd/epg.dat", cnt);
768 eDebug("[EPGC] don't read old epg database");
775 void eEPGCache::save()
780 if (statfs("/hdd", &s)<0)
788 // prevent writes to builtin flash
789 if ( tmp < 1024*1024*50 ) // storage size < 50MB
792 // check for enough free space on storage
795 if ( tmp < (eventData::CacheSize*12)/10 ) // 20% overhead
798 FILE *f = fopen("/hdd/epg.dat", "w");
802 const char *text = "ENIGMA_EPG_V2";
803 fwrite( text, 13, 1, f );
804 int size = eventDB.size();
805 fwrite( &size, sizeof(int), 1, f );
806 for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it)
808 timeMap &timemap = service_it->second.second;
809 fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f);
810 size = timemap.size();
811 fwrite( &size, sizeof(int), 1, f);
812 for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it)
814 int len = time_it->second->ByteSize;
815 fwrite( &time_it->second->type, sizeof(int), 1, f );
816 fwrite( &len, sizeof(int), 1, f);
817 fwrite( time_it->second->EITdata, len, 1, f);
821 eDebug("%d events written to /hdd/epg.dat", cnt);
824 unsigned char md5[16];
825 if (!md5_file("/hdd/epg.dat", 1, md5))
827 FILE *f = fopen("/hdd/epg.dat.md5", "w");
830 fwrite( md5, 16, 1, f);
838 RESULT eEPGCache::getInstance(ePtr<eEPGCache> &ptr)
846 eEPGCache::channel_data::channel_data(eEPGCache *ml)
848 ,abortTimer(ml), zapTimer(ml)
849 ,state(0), isRunning(0), haveData(0), can_delete(1)
851 CONNECT(zapTimer.timeout, eEPGCache::channel_data::startEPG);
852 CONNECT(abortTimer.timeout, eEPGCache::channel_data::abortNonAvail);
855 bool eEPGCache::channel_data::finishEPG()
857 if (!isRunning) // epg ready
859 eDebug("[EPGC] stop caching events(%d)", time(0)+eDVBLocalTimeHandler::getInstance()->difference());
860 zapTimer.start(UPDATE_INTERVAL, 1);
861 eDebug("[EPGC] next update in %i min", UPDATE_INTERVAL / 60000);
862 for (int i=0; i < 3; ++i)
864 seenSections[i].clear();
865 calcedSections[i].clear();
867 singleLock l(cache->cache_lock);
868 cache->channelLastUpdated[channel->getChannelID()] = time(0)+eDVBLocalTimeHandler::getInstance()->difference();
875 void eEPGCache::channel_data::startEPG()
877 eDebug("[EPGC] start caching events(%d)", eDVBLocalTimeHandler::getInstance()->difference()+time(0));
881 for (int i=0; i < 3; ++i)
883 seenSections[i].clear();
884 calcedSections[i].clear();
887 eDVBSectionFilterMask mask;
888 memset(&mask, 0, sizeof(mask));
890 mask.flags = eDVBSectionFilterMask::rfCRC;
894 m_NowNextReader->start(mask);
895 isRunning |= NOWNEXT;
899 m_ScheduleReader->start(mask);
900 isRunning |= SCHEDULE;
904 m_ScheduleOtherReader->start(mask);
905 isRunning |= SCHEDULE_OTHER;
907 abortTimer.start(7000,true);
910 void eEPGCache::channel_data::abortNonAvail()
914 if ( !(haveData&eEPGCache::NOWNEXT) && (isRunning&eEPGCache::NOWNEXT) )
916 eDebug("[EPGC] abort non avail nownext reading");
917 isRunning &= ~eEPGCache::NOWNEXT;
918 if ( m_NowNextReader )
919 m_NowNextReader->stop();
921 if ( !(haveData&eEPGCache::SCHEDULE) && (isRunning&eEPGCache::SCHEDULE) )
923 eDebug("[EPGC] abort non avail schedule reading");
924 isRunning &= ~SCHEDULE;
925 m_ScheduleReader->stop();
927 if ( !(haveData&eEPGCache::SCHEDULE_OTHER) && (isRunning&eEPGCache::SCHEDULE_OTHER) )
929 eDebug("[EPGC] abort non avail schedule_other reading");
930 isRunning &= ~SCHEDULE_OTHER;
931 m_ScheduleOtherReader->stop();
934 abortTimer.start(90000, true);
938 for (int i=0; i < 3; ++i)
940 seenSections[i].clear();
941 calcedSections[i].clear();
949 void eEPGCache::channel_data::startChannel()
951 updateMap::iterator It = cache->channelLastUpdated.find( channel->getChannelID() );
953 int update = ( It != cache->channelLastUpdated.end() ? ( UPDATE_INTERVAL - ( (time(0)+eDVBLocalTimeHandler::getInstance()->difference()-It->second) * 1000 ) ) : ZAP_DELAY );
955 if (update < ZAP_DELAY)
958 zapTimer.start(update, 1);
960 eDebug("[EPGC] next update in %i min", update/60000);
961 else if (update >= 1000)
962 eDebug("[EPGC] next update in %i sec", update/1000);
965 void eEPGCache::channel_data::abortEPG()
967 for (int i=0; i < 3; ++i)
969 seenSections[i].clear();
970 calcedSections[i].clear();
976 eDebug("[EPGC] abort caching events !!");
977 if (isRunning & eEPGCache::SCHEDULE)
979 isRunning &= eEPGCache::SCHEDULE;
980 if ( m_ScheduleReader )
981 m_ScheduleReader->stop();
983 if (isRunning & eEPGCache::NOWNEXT)
985 isRunning &= ~eEPGCache::NOWNEXT;
986 if ( m_NowNextReader )
987 m_NowNextReader->stop();
989 if (isRunning & SCHEDULE_OTHER)
991 isRunning &= ~eEPGCache::SCHEDULE_OTHER;
992 if ( m_ScheduleOtherReader )
993 m_ScheduleOtherReader->stop();
999 void eEPGCache::channel_data::readData( const __u8 *data)
1002 eDebug("get Null pointer from section reader !!");
1007 iDVBSectionReader *reader=NULL;
1011 reader=m_NowNextReader;
1012 source=eEPGCache::NOWNEXT;
1016 reader=m_ScheduleReader;
1017 source=eEPGCache::SCHEDULE;
1021 reader=m_ScheduleOtherReader;
1022 source=eEPGCache::SCHEDULE_OTHER;
1026 eDebug("[EPGC] unknown table_id !!!");
1029 tidMap &seenSections = this->seenSections[map];
1030 tidMap &calcedSections = this->calcedSections[map];
1031 if ( state == 1 && calcedSections == seenSections || state > 1 )
1033 eDebugNoNewLine("[EPGC] ");
1036 case eEPGCache::NOWNEXT: eDebugNoNewLine("nownext");break;
1037 case eEPGCache::SCHEDULE: eDebugNoNewLine("schedule");break;
1038 case eEPGCache::SCHEDULE_OTHER: eDebugNoNewLine("schedule other");break;
1039 default: eDebugNoNewLine("unknown");break;
1041 eDebug(" finished(%d)", time(0)+eDVBLocalTimeHandler::getInstance()->difference());
1044 isRunning &= ~source;
1050 eit_t *eit = (eit_t*) data;
1051 __u32 sectionNo = data[0] << 24;
1052 sectionNo |= data[3] << 16;
1053 sectionNo |= data[4] << 8;
1054 sectionNo |= eit->section_number;
1056 tidMap::iterator it =
1057 seenSections.find(sectionNo);
1059 if ( it == seenSections.end() )
1061 seenSections.insert(sectionNo);
1062 calcedSections.insert(sectionNo);
1063 __u32 tmpval = sectionNo & 0xFFFFFF00;
1064 __u8 incr = source == NOWNEXT ? 1 : 8;
1065 for ( int i = 0; i <= eit->last_section_number; i+=incr )
1067 if ( i == eit->section_number )
1069 for (int x=i; x <= eit->segment_last_section_number; ++x)
1070 calcedSections.insert(tmpval|(x&0xFF));
1073 calcedSections.insert(tmpval|(i&0xFF));
1075 cache->sectionRead(data, source, this);