X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fepgcache.cpp;h=8ac0c7188c1728203f7fe25a49cb70539af74ca0;hp=2dc36412d5fbdaa2a3dc1d8ced90755e95afab9c;hb=30da484f79db1d8210a3dcb31b359484873dc240;hpb=7c85ede71f2779a544fb9094d5ea2a170ee4a76b diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index 2dc3641..8ac0c71 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->second)); + } + } + } 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) @@ -255,6 +279,11 @@ void eEPGCache::DVBChannelAdded(eDVBChannel *chan) #ifdef ENABLE_PRIVATE_EPG data->m_PrivatePid = -1; #endif +#ifdef ENABLE_MHW_EPG + data->m_mhw2_channel_pid = 0x231; // defaults for astra 19.2 D+ + data->m_mhw2_title_pid = 0x234; // defaults for astra 19.2 D+ + data->m_mhw2_summary_pid = 0x236; // defaults for astra 19.2 D+ +#endif singleLock s(channel_map_lock); m_knownChannels.insert( std::pair(chan, data) ); chan->connectStateChange(slot(*this, &eEPGCache::DVBChannelStateChanged), data->m_stateChangedConn); @@ -332,8 +361,11 @@ 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 + } } } } @@ -360,7 +392,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); @@ -880,6 +913,62 @@ void eEPGCache::gotMessage( const Message &msg ) break; } #endif +#ifdef ENABLE_MHW_EPG + case Message::got_mhw2_channel_pid: + { + singleLock s(channel_map_lock); + for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it) + { + eDVBChannel *channel = (eDVBChannel*) it->first; + channel_data *data = it->second; + eDVBChannelID chid = channel->getChannelID(); + if ( chid.transport_stream_id.get() == msg.service.tsid && + chid.original_network_id.get() == msg.service.onid ) + { + data->m_mhw2_channel_pid = msg.pid; + eDebug("[EPGC] got mhw2 channel pid %04x", msg.pid); + break; + } + } + break; + } + case Message::got_mhw2_title_pid: + { + singleLock s(channel_map_lock); + for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it) + { + eDVBChannel *channel = (eDVBChannel*) it->first; + channel_data *data = it->second; + eDVBChannelID chid = channel->getChannelID(); + if ( chid.transport_stream_id.get() == msg.service.tsid && + chid.original_network_id.get() == msg.service.onid ) + { + data->m_mhw2_title_pid = msg.pid; + eDebug("[EPGC] got mhw2 title pid %04x", msg.pid); + break; + } + } + break; + } + case Message::got_mhw2_summary_pid: + { + singleLock s(channel_map_lock); + for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it) + { + eDVBChannel *channel = (eDVBChannel*) it->first; + channel_data *data = it->second; + eDVBChannelID chid = channel->getChannelID(); + if ( chid.transport_stream_id.get() == msg.service.tsid && + chid.original_network_id.get() == msg.service.onid ) + { + data->m_mhw2_summary_pid = msg.pid; + eDebug("[EPGC] got mhw2 summary pid %04x", msg.pid); + break; + } + } + break; + } +#endif case Message::timeChanged: cleanLoop(); break; @@ -892,39 +981,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); @@ -966,7 +1040,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); @@ -1014,103 +1088,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(-1) ,isRunning(0), haveData(0) #ifdef ENABLE_PRIVATE_EPG ,startPrivateTimer(eTimer::create(ml)) @@ -1175,7 +1252,7 @@ void eEPGCache::channel_data::startEPG() isRunning |= MHW; memcpy(&m_MHWFilterMask, &mask, sizeof(eDVBSectionFilterMask)); - mask.pid = 0x231; + mask.pid = m_mhw2_channel_pid; mask.data[0] = 0xC8; mask.mask[0] = 0xFF; mask.data[1] = 0; @@ -1186,6 +1263,7 @@ void eEPGCache::channel_data::startEPG() memcpy(&m_MHWFilterMask2, &mask, sizeof(eDVBSectionFilterMask)); mask.data[1] = 0; mask.mask[1] = 0; + m_MHWTimeoutet=false; #endif mask.pid = 0x12; @@ -1395,7 +1473,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) @@ -2489,6 +2567,50 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler) int tmp=0; switch ((*es)->getType()) { + case 0xC1: // user private + for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); + desc != (*es)->getDescriptors()->end(); ++desc) + { + switch ((*desc)->getTag()) + { + case 0xC2: // user defined + if ((*desc)->getLength() == 8) + { + __u8 buffer[10]; + (*desc)->writeToBuffer(buffer); + if (!strncmp((const char *)buffer+2, "EPGDATA", 7)) + { + eServiceReferenceDVB ref; + if (!pmthandler->getServiceReference(ref)) + { + int pid = (*es)->getPid(); + messages.send(Message(Message::got_mhw2_channel_pid, ref, pid)); + } + } + else if(!strncmp((const char *)buffer+2, "FICHAS", 6)) + { + eServiceReferenceDVB ref; + if (!pmthandler->getServiceReference(ref)) + { + int pid = (*es)->getPid(); + messages.send(Message(Message::got_mhw2_summary_pid, ref, pid)); + } + } + else if(!strncmp((const char *)buffer+2, "GENEROS", 7)) + { + eServiceReferenceDVB ref; + if (!pmthandler->getServiceReference(ref)) + { + int pid = (*es)->getPid(); + messages.send(Message(Message::got_mhw2_title_pid, ref, pid)); + } + } + } + break; + default: + break; + } + } case 0x05: // private for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) @@ -2893,7 +3015,7 @@ void eEPGCache::channel_data::storeTitle(std::map<__u32, mhw_title_t>::iterator packet->segment_last_table_id = 0x50; __u8 *title = isMHW2 ? ((__u8*)(itTitle->second.title))-4 : (__u8*)itTitle->second.title; - std::string prog_title = (char *) delimitName( title, name, isMHW2 ? 33 : 23 ); + std::string prog_title = (char *) delimitName( title, name, isMHW2 ? 35 : 23 ); int prog_title_length = prog_title.length(); int packet_length = EIT_SIZE + EIT_LOOP_SIZE + EIT_SHORT_EVENT_DESCRIPTOR_SIZE + @@ -3222,14 +3344,14 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data) { eDebug("[EPGC] mhw2 aborted %d", state); } - else if (m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0) + else if (m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0) // Channels table { - int num_channels = data[119]; + int num_channels = data[120]; m_channels.resize(num_channels); - if(dataLen > 119) + if(dataLen > 120) { - int ptr = 120 + 8 * num_channels; + int ptr = 121 + 8 * num_channels; if( dataLen > ptr ) { for( int chid = 0; chid < num_channels; ++chid ) @@ -3245,7 +3367,7 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data) else goto abort; // data seems consistent... - const __u8 *tmp = data+120; + const __u8 *tmp = data+121; for (int i=0; i < num_channels; ++i) { mhw_channel_name_t channel; @@ -3256,6 +3378,7 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data) channel.channel_id_hi = *(tmp++); channel.channel_id_lo = *(tmp++); m_channels[i]=channel; +// eDebug("%d(%02x) %04x: %02x %02x", i, i, (channel.channel_id_hi << 8) | channel.channel_id_lo, *tmp, *(tmp+1)); tmp+=2; } for (int i=0; i < num_channels; ++i) @@ -3266,83 +3389,86 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data) for (; x < channel_name_len; ++x) channel.name[x]=*(tmp++); channel.name[x+1]=0; +// eDebug("%d(%02x) %s", i, i, channel.name); } haveData |= MHW; eDebug("[EPGC] mhw2 %d channels found", m_channels.size()); } - else if (m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1) + else if (m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1) { // Themes table eDebug("[EPGC] mhw2 themes nyi"); } - else if (m_MHWFilterMask2.pid == 0x234 && m_MHWFilterMask2.data[0] == 0xe6) + else if (m_MHWFilterMask2.pid == m_mhw2_title_pid && m_MHWFilterMask2.data[0] == 0xe6) // Titles table { int pos=18; - bool valid=true; - int len = ((data[1]&0xf)<<8) + data[2] - 16; + bool valid=false; bool finish=false; - if(data[dataLen-1] != 0xff) - return; - while( pos < dataLen ) + +// eDebug("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", +// data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], +// data[11], data[12], data[13], data[14], data[15], data[16], data[17] ); + + while( pos < dataLen && !valid) { - valid = false; - pos += 7; - if( pos < dataLen ) - { - pos += 3; - if( pos < dataLen ) - { - if( data[pos] > 0xc0 ) - { - pos += ( data[pos] - 0xc0 ); - pos += 4; - if( pos < dataLen ) - { - if( data[pos] == 0xff ) - { - ++pos; - valid = true; - } - } - } - } - } - if( !valid ) - { - if (checkTimeout()) - goto start_summary; - return; - } + pos += 18; + pos += (data[pos] & 0x3F) + 4; + if( pos == dataLen ) + valid = true; + } + + if (!valid) + { + if (dataLen > 18) + eDebug("mhw2 title table invalid!!"); + if (checkTimeout()) + goto abort; + if (!m_MHWTimeoutTimer->isActive()) + startTimeout(5000); + return; // continue reading } + // data seems consistent... mhw_title_t title; pos = 18; - while (pos < len) + while (pos < dataLen) { +// eDebugNoNewLine(" [%02x] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x [%02x %02x %02x %02x %02x %02x %02x] LL - DESCR - ", +// data[pos], data[pos+1], data[pos+2], data[pos+3], data[pos+4], data[pos+5], data[pos+6], data[pos+7], +// data[pos+8], data[pos+9], data[pos+10], data[pos+11], data[pos+12], data[pos+13], data[pos+14], data[pos+15], data[pos+16], data[pos+17]); title.channel_id = data[pos]+1; - title.program_id_ml = data[pos+1]; - title.program_id_lo = data[pos+2]; - title.mhw2_mjd_hi = data[pos+3]; - title.mhw2_mjd_lo = data[pos+4]; - title.mhw2_hours = data[pos+5]; - title.mhw2_minutes = data[pos+6]; - title.mhw2_seconds = data[pos+7]; - int duration = ((data[pos+8] << 8)|data[pos+9]) >> 4; + title.mhw2_mjd_hi = data[pos+11]; + title.mhw2_mjd_lo = data[pos+12]; + title.mhw2_hours = data[pos+13]; + title.mhw2_minutes = data[pos+14]; + title.mhw2_seconds = data[pos+15]; + int duration = ((data[pos+16] << 8)|data[pos+17]) >> 4; title.mhw2_duration_hi = (duration&0xFF00) >> 8; title.mhw2_duration_lo = duration&0xFF; - __u8 slen = data[pos+10] & 0x3f; + + // Create unique key per title + __u32 title_id = (data[pos+7] << 24) | (data[pos+8] << 16) | (data[pos+9] << 8) | data[pos+10]; + + __u8 slen = data[pos+18] & 0x3f; __u8 *dest = ((__u8*)title.title)-4; - memcpy(dest, &data[pos+11], slen>33 ? 33 : slen); - memset(dest+slen, 0, 33-slen); - pos += 11 + slen; + memcpy(dest, &data[pos+19], slen>35 ? 35 : slen); + memset(dest+slen, 0, 35-slen); + pos += 19 + slen; +// eDebug("%02x [%02x %02x]: %s", data[pos], data[pos+1], data[pos+2], dest); + // not used theme id (data[7] & 0x3f) + (data[pos] & 0x3f); __u32 summary_id = (data[pos+1] << 8) | data[pos+2]; - // Create unique key per title - __u32 title_id = (title.channel_id<<16) | (title.program_id_ml<<8) | title.program_id_lo; +// if (title.channel_id > m_channels.size()) +// eDebug("channel_id(%d %02x) to big!!", title.channel_id); + +// eDebug("pos %d prog_id %02x %02x chid %02x summary_id %04x dest %p len %d\n", +// pos, title.program_id_ml, title.program_id_lo, title.channel_id, summary_id, dest, slen); + +// eDebug("title_id %08x -> summary_id %04x\n", title_id, summary_id); - pos += 4; + pos += 3; std::map<__u32, mhw_title_t>::iterator it = m_titles.find( title_id ); if ( it == m_titles.end() ) @@ -3381,7 +3507,7 @@ start_summary: { // Titles table has been read, there are summaries to read. // Start reading summaries, store corresponding titles on the fly. - startMHWReader2(0x236, 0x96); + startMHWReader2(m_mhw2_summary_pid, 0x96); startTimeout(15000); return; } @@ -3389,7 +3515,7 @@ start_summary: else return; } - else if (m_MHWFilterMask2.pid == 0x236 && m_MHWFilterMask2.data[0] == 0x96) + else if (m_MHWFilterMask2.pid == m_mhw2_summary_pid && m_MHWFilterMask2.data[0] == 0x96) // Summaries table { if (!checkTimeout()) @@ -3423,10 +3549,13 @@ start_summary: } else return; // continue reading + if (valid) { // data seems consistent... __u32 summary_id = (data[3]<<8)|data[4]; +// eDebug ("summary id %04x\n", summary_id); +// eDebug("[%02x %02x] %02x %02x %02x %02x %02x %02x %02x %02x XX\n", data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13] ); // ugly workaround to convert const __u8* to char* char *tmp=0; @@ -3444,7 +3573,7 @@ start_summary: len += lenline + 1; } if( len > 0 ) - tmp[pos+len] = 0; + tmp[pos+len] = 0; else tmp[pos+1] = 0; @@ -3460,8 +3589,11 @@ start_summary: startTimeout(15000); std::string the_text = (char *) (data + pos + 1); +// eDebug ("summary id %04x : %s\n", summary_id, data+pos+1); + while( itProgId != m_program_ids.end() && itProgId->first == summary_id ) { +// eDebug("."); // Find corresponding title, store title and summary in epgcache. std::map<__u32, mhw_title_t>::iterator itTitle( m_titles.find( itProgId->second ) ); if ( itTitle != m_titles.end() ) @@ -3481,16 +3613,16 @@ start_summary: } if (isRunning & eEPGCache::MHW) { - if ( m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0) + if ( m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0) { // Channels table has been read, start reading the themes table. - startMHWReader2(0x231, 0xC8, 1); + startMHWReader2(m_mhw2_channel_pid, 0xC8, 1); return; } - else if ( m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1) + else if ( m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1) { // Themes table has been read, start reading the titles table. - startMHWReader2(0x234, 0xe6); + startMHWReader2(m_mhw2_title_pid, 0xe6); return; } else