X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fepgcache.cpp;h=4d32474663941ec9c78322205f551a4ac8da2f36;hp=48cbfbfdf4dc378621276d0d34fb3dcfb3668c3e;hb=ad4c850143eee2e993d1637a12d9418279ac32d3;hpb=ca13d7906607bb7be40e7695e36054b8b86c8529 diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index 48cbfbf..4d32474 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -213,9 +213,9 @@ pthread_mutex_t eEPGCache::channel_map_lock= DEFINE_REF(eEPGCache) eEPGCache::eEPGCache() - :messages(this,1), cleanTimer(eTimer::create(this))//, paused(0) + :messages(this,1), cleanTimer(eTimer::create(this)), m_running(0)//, paused(0) { - eDebug("[EPGC] Initialized EPGCache"); + eDebug("[EPGC] Initialized EPGCache (wait for setCacheFile call now)"); CONNECT(messages.recv_msg, eEPGCache::gotMessage); CONNECT(eDVBLocalTimeHandler::getInstance()->m_timeUpdated, eEPGCache::timeUpdated); @@ -226,22 +226,46 @@ eEPGCache::eEPGCache() if (!res_mgr) eDebug("[eEPGCache] no resource manager !!!!!!!"); else - { res_mgr->connectChannelAdded(slot(*this,&eEPGCache::DVBChannelAdded), m_chanAddedConn); + + instance=this; + memset(m_filename, 0, sizeof(m_filename)); +} + +void eEPGCache::setCacheFile(const char *path) +{ + bool inited = !!strlen(m_filename); + strncpy(m_filename, path, 1024); + if (!inited) + { + eDebug("[EPGC] setCacheFile read/write epg data from/to '%s'", m_filename); if (eDVBLocalTimeHandler::getInstance()->ready()) timeUpdated(); } - instance=this; } void eEPGCache::timeUpdated() { - if (!sync()) + if (strlen(m_filename)) { - eDebug("[EPGC] time updated.. start EPG Mainloop"); - run(); - } else - messages.send(Message(Message::timeChanged)); + if (!sync()) + { + eDebug("[EPGC] time updated.. start EPG Mainloop"); + run(); + singleLock s(channel_map_lock); + channelMapIterator it = m_knownChannels.begin(); + for (; it != m_knownChannels.end(); ++it) + { + if (it->second->state == -1) { + it->second->state=0; + messages.send(Message(Message::startChannel, it->first)); + } + } + } else + messages.send(Message(Message::timeChanged)); + } + else + eDebug("[EPGC] time updated.. but cache file not set yet.. dont start epg!!"); } void eEPGCache::DVBChannelAdded(eDVBChannel *chan) @@ -337,8 +361,13 @@ void eEPGCache::DVBChannelRunning(iDVBChannel *chan) return; } #endif - messages.send(Message(Message::startChannel, chan)); - // -> gotMessage -> changedService + if (m_running) { + data.state=0; + messages.send(Message(Message::startChannel, chan)); + // -> gotMessage -> changedService + } + else + data.state=-1; } } } @@ -365,7 +394,8 @@ void eEPGCache::DVBChannelStateChanged(iDVBChannel *chan) case iDVBChannel::state_release: { eDebug("[eEPGCache] remove channel %p", chan); - messages.send(Message(Message::leaveChannel, chan)); + if (it->second->state >= 0) + messages.send(Message(Message::leaveChannel, chan)); pthread_mutex_lock(&it->second->channel_active); singleLock s(channel_map_lock); m_knownChannels.erase(it); @@ -953,39 +983,24 @@ void eEPGCache::gotMessage( const Message &msg ) void eEPGCache::thread() { hasStarted(); + m_running=1; nice(4); load(); cleanLoop(); runLoop(); save(); + m_running=0; } void eEPGCache::load() { - FILE *f = fopen("/hdd/epg.dat", "r"); + FILE *f = fopen(m_filename, "r"); if (f) { - unlink("/hdd/epg.dat"); + unlink(m_filename); int size=0; int cnt=0; -#if 0 - unsigned char md5_saved[16]; - unsigned char md5[16]; - bool md5ok=false; - if (!md5_file("/hdd/epg.dat", 1, md5)) - { - FILE *f = fopen("/hdd/epg.dat.md5", "r"); - if (f) - { - fread( md5_saved, 16, 1, f); - fclose(f); - if ( !memcmp(md5_saved, md5, 16) ) - md5ok=true; - } - } - if ( md5ok ) -#endif { unsigned int magic=0; fread( &magic, sizeof(int), 1, f); @@ -1027,7 +1042,7 @@ void eEPGCache::load() eventDB[key]=std::pair(evMap,tmMap); } eventData::load(f); - eDebug("[EPGC] %d events read from /hdd/epg.dat", cnt); + eDebug("[EPGC] %d events read from %s", cnt, m_filename); #ifdef ENABLE_PRIVATE_EPG char text2[11]; fread( text2, 11, 1, f); @@ -1075,103 +1090,106 @@ void eEPGCache::load() void eEPGCache::save() { - struct statfs s; - off64_t tmp; - if (statfs("/hdd", &s)<0) - tmp=0; - else + /* create empty file */ + FILE *f = fopen(m_filename, "w"); + + if (!f) { - tmp=s.f_blocks; - tmp*=s.f_bsize; + eDebug("[EPGC] couldn't save epg data to '%s'(%m)", m_filename); + return; } - // prevent writes to builtin flash - if ( tmp < 1024*1024*50 ) // storage size < 50MB + char *buf = realpath(m_filename, NULL); + if (!buf) + { + eDebug("[EPGC] realpath to '%s' failed in save (%m)", m_filename); + fclose(f); return; + } + + eDebug("[EPGC] store epg to realpath '%s'", buf); + + struct statfs s; + off64_t tmp; + if (statfs(buf, &s) < 0) { + eDebug("[EPGC] statfs '%s' failed in save (%m)", buf); + fclose(f); + return; + } + + free(buf); // check for enough free space on storage tmp=s.f_bfree; tmp*=s.f_bsize; if ( tmp < (eventData::CacheSize*12)/10 ) // 20% overhead + { + eDebug("[EPGC] not enough free space at path '%s' %lld bytes availd but %d needed", buf, tmp, (eventData::CacheSize*12)/10); + fclose(f); return; + } - FILE *f = fopen("/hdd/epg.dat", "w"); int cnt=0; - if ( f ) - { - unsigned int magic = 0x98765432; - fwrite( &magic, sizeof(int), 1, f); - const char *text = "UNFINISHED_V7"; - fwrite( text, 13, 1, f ); - int size = eventDB.size(); - fwrite( &size, sizeof(int), 1, f ); - for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it) - { - timeMap &timemap = service_it->second.second; - fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f); - size = timemap.size(); - fwrite( &size, sizeof(int), 1, f); - for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it) - { - __u8 len = time_it->second->ByteSize; - fwrite( &time_it->second->type, sizeof(__u8), 1, f ); - fwrite( &len, sizeof(__u8), 1, f); - fwrite( time_it->second->EITdata, len, 1, f); - ++cnt; - } + unsigned int magic = 0x98765432; + fwrite( &magic, sizeof(int), 1, f); + const char *text = "UNFINISHED_V7"; + fwrite( text, 13, 1, f ); + int size = eventDB.size(); + fwrite( &size, sizeof(int), 1, f ); + for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it) + { + timeMap &timemap = service_it->second.second; + fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f); + size = timemap.size(); + fwrite( &size, sizeof(int), 1, f); + for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it) + { + __u8 len = time_it->second->ByteSize; + fwrite( &time_it->second->type, sizeof(__u8), 1, f ); + fwrite( &len, sizeof(__u8), 1, f); + fwrite( time_it->second->EITdata, len, 1, f); + ++cnt; } - eDebug("[EPGC] %d events written to /hdd/epg.dat", cnt); - eventData::save(f); + } + eDebug("[EPGC] %d events written to %s", cnt, m_filename); + eventData::save(f); #ifdef ENABLE_PRIVATE_EPG - const char* text3 = "PRIVATE_EPG"; - fwrite( text3, 11, 1, f ); - size = content_time_tables.size(); + const char* text3 = "PRIVATE_EPG"; + fwrite( text3, 11, 1, f ); + size = content_time_tables.size(); + fwrite( &size, sizeof(int), 1, f); + for (contentMaps::iterator a = content_time_tables.begin(); a != content_time_tables.end(); ++a) + { + contentMap &content_time_table = a->second; + fwrite( &a->first, sizeof(uniqueEPGKey), 1, f); + int size = content_time_table.size(); fwrite( &size, sizeof(int), 1, f); - for (contentMaps::iterator a = content_time_tables.begin(); a != content_time_tables.end(); ++a) + for (contentMap::iterator i = content_time_table.begin(); i != content_time_table.end(); ++i ) { - contentMap &content_time_table = a->second; - fwrite( &a->first, sizeof(uniqueEPGKey), 1, f); - int size = content_time_table.size(); + int size = i->second.size(); + fwrite( &i->first, sizeof(int), 1, f); fwrite( &size, sizeof(int), 1, f); - for (contentMap::iterator i = content_time_table.begin(); i != content_time_table.end(); ++i ) - { - int size = i->second.size(); - fwrite( &i->first, sizeof(int), 1, f); - fwrite( &size, sizeof(int), 1, f); - for ( contentTimeMap::iterator it(i->second.begin()); - it != i->second.end(); ++it ) - { - fwrite( &it->first, sizeof(time_t), 1, f); - fwrite( &it->second.first, sizeof(time_t), 1, f); - fwrite( &it->second.second, sizeof(__u16), 1, f); - } - } - } -#endif - // write version string after binary data - // has been written to disk. - fsync(fileno(f)); - fseek(f, sizeof(int), SEEK_SET); - fwrite("ENIGMA_EPG_V7", 13, 1, f); - fclose(f); -#if 0 - unsigned char md5[16]; - if (!md5_file("/hdd/epg.dat", 1, md5)) - { - FILE *f = fopen("/hdd/epg.dat.md5", "w"); - if (f) + for ( contentTimeMap::iterator it(i->second.begin()); + it != i->second.end(); ++it ) { - fwrite( md5, 16, 1, f); - fclose(f); + fwrite( &it->first, sizeof(time_t), 1, f); + fwrite( &it->second.first, sizeof(time_t), 1, f); + fwrite( &it->second.second, sizeof(__u16), 1, f); } } -#endif } +#endif + // write version string after binary data + // has been written to disk. + fsync(fileno(f)); + fseek(f, sizeof(int), SEEK_SET); + fwrite("ENIGMA_EPG_V7", 13, 1, f); + fclose(f); } eEPGCache::channel_data::channel_data(eEPGCache *ml) :cache(ml) - ,abortTimer(eTimer::create(ml)), zapTimer(eTimer::create(ml)), state(0) + ,abortTimer(eTimer::create(ml)), zapTimer(eTimer::create(ml)), state(-2) ,isRunning(0), haveData(0) #ifdef ENABLE_PRIVATE_EPG ,startPrivateTimer(eTimer::create(ml)) @@ -1457,7 +1475,7 @@ void eEPGCache::channel_data::readData( const __u8 *data) } tidMap &seenSections = this->seenSections[map]; tidMap &calcedSections = this->calcedSections[map]; - if ( state == 1 && calcedSections == seenSections || state > 1 ) + if ( (state == 1 && calcedSections == seenSections) || state > 1 ) { eDebugNoNewLine("[EPGC] "); switch (source) @@ -2562,7 +2580,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler) { __u8 buffer[10]; (*desc)->writeToBuffer(buffer); - if (!strncmp((unsigned char*)buffer+2, "EPGDATA", 7)) + if (!strncmp((const char *)buffer+2, "EPGDATA", 7)) { eServiceReferenceDVB ref; if (!pmthandler->getServiceReference(ref)) @@ -2571,7 +2589,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler) messages.send(Message(Message::got_mhw2_channel_pid, ref, pid)); } } - else if(!strncmp((unsigned char*)buffer+2, "FICHAS", 6)) + else if(!strncmp((const char *)buffer+2, "FICHAS", 6)) { eServiceReferenceDVB ref; if (!pmthandler->getServiceReference(ref)) @@ -2580,7 +2598,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler) messages.send(Message(Message::got_mhw2_summary_pid, ref, pid)); } } - else if(!strncmp((unsigned char*)buffer+2, "GENEROS", 7)) + else if(!strncmp((const char *)buffer+2, "GENEROS", 7)) { eServiceReferenceDVB ref; if (!pmthandler->getServiceReference(ref))