X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/8b0a581bf9ec96b6b698fa2d236d2aadc417f9da..fd2f20e9411cb4e6a4667d51908fb82aa6b1d502:/lib/dvb/dvbtime.cpp diff --git a/lib/dvb/dvbtime.cpp b/lib/dvb/dvbtime.cpp index 795b5242..7684bfa4 100644 --- a/lib/dvb/dvbtime.cpp +++ b/lib/dvb/dvbtime.cpp @@ -62,21 +62,21 @@ time_t parseDVBtime(__u8 t1, __u8 t2, __u8 t3, __u8 t4, __u8 t5) return timegm(&t); } -TDT::TDT(eDVBChannel *chan) - :chan(chan) +TDT::TDT(eDVBChannel *chan, int update_count) + :chan(chan), update_count(update_count) { CONNECT(tableReady, TDT::ready); CONNECT(m_interval_timer.timeout, TDT::start); if (chan) - chan->getDemux(demux); + chan->getDemux(demux, 0); } void TDT::ready(int error) { - eDVBLocalTimeHandler::getInstance()->updateTime(error, chan); + eDVBLocalTimeHandler::getInstance()->updateTime(error, chan, ++update_count); } -int TDT::createTable(int nr, const __u8 *data, unsigned int max) +int TDT::createTable(unsigned int nr, const __u8 *data, unsigned int max) { if ( data && data[0] == 0x70 || data[0] == 0x73 ) { @@ -84,7 +84,8 @@ int TDT::createTable(int nr, const __u8 *data, unsigned int max) if ( length >= 5 ) { time_t tptime = parseDVBtime(data[3], data[4], data[5], data[6], data[7]); - eDVBLocalTimeHandler::getInstance()->updateTime(tptime, chan); + if (tptime && tptime != -1) + eDVBLocalTimeHandler::getInstance()->updateTime(tptime, chan, update_count); error=0; return 1; } @@ -97,10 +98,10 @@ void TDT::start() if ( chan ) { eDVBTableSpec spec; - spec.pid = TimeAndDateTable::PID; - spec.tid = TimeAndDateTable::TID; + spec.pid = TimeAndDateSection::PID; + spec.tid = TimeAndDateSection::TID; spec.tid_mask = 0xFC; - spec.timeout = TimeAndDateTable::TIMEOUT; + spec.timeout = TimeAndDateSection::TIMEOUT; spec.flags= eDVBTableSpec::tfAnyVersion | eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfHaveTIDMask | @@ -128,7 +129,18 @@ eDVBLocalTimeHandler::eDVBLocalTimeHandler() if (!res_mgr) eDebug("[eDVBLocalTimerHandler] no resource manager !!!!!!!"); else + { res_mgr->connectChannelAdded(slot(*this,&eDVBLocalTimeHandler::DVBChannelAdded), m_chanAddedConn); + time_t now = time(0); + if ( now < 1072224000 ) // 01.01.2004 + eDebug("RTC not ready... wait for transponder time"); + else // inform all who's waiting for valid system time.. + { + eDebug("Use valid Linux Time :) (RTC?)"); + m_time_ready = true; + /*emit*/ m_timeUpdated(); + } + } } eDVBLocalTimeHandler::~eDVBLocalTimeHandler() @@ -136,6 +148,11 @@ eDVBLocalTimeHandler::~eDVBLocalTimeHandler() instance=0; for (std::map::iterator it=m_knownChannels.begin(); it != m_knownChannels.end(); ++it) delete it->second.tdt; + if (ready()) + { + eDebug("set RTC to previous valid time"); + setRTC(nowTime()); + } } void eDVBLocalTimeHandler::readTimeOffsetData( const char* filename ) @@ -173,10 +190,10 @@ void eDVBLocalTimeHandler::writeTimeOffsetData( const char* filename ) } } -void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) +void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int update_count ) { bool restart_tdt = false; - if (!tp_time ) + if (!tp_time) restart_tdt = true; else if (tp_time == -1) { @@ -189,20 +206,21 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) time_t rtc_time = getRTC(); if ( rtc_time ) // RTC Ready? { - tm now = *localtime(&rtc_time); + tm now; + localtime_r(&rtc_time, &now); eDebug("[eDVBLocalTimerHandler] RTC time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_t linuxTime=time(0); time_t nowTime=linuxTime+m_time_difference; - now = *localtime(&nowTime); + localtime_r(&nowTime, &now); eDebug("[eDVBLocalTimerHandler] Receiver time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); m_time_difference = rtc_time - linuxTime; - eDebug("[eDVBLocalTimerHandler] RTC to Receiver time difference is %d seconds", nowTime - rtc_time ); + eDebug("[eDVBLocalTimerHandler] RTC to Receiver time difference is %ld seconds", nowTime - rtc_time ); if ( abs(m_time_difference) > 59 ) { eDebug("[eDVBLocalTimerHandler] set Linux Time to RTC Time"); @@ -210,9 +228,7 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) gettimeofday(&tnow,0); tnow.tv_sec=rtc_time; settimeofday(&tnow,0); - for (ePtrList::iterator it(eMainloop::existing_loops) - ;it != eMainloop::existing_loops.end(); ++it) - it->setTimerOffset(m_time_difference); + eMainloop::addTimeOffset(m_time_difference); m_time_difference=0; } else if ( !m_time_difference ) @@ -240,6 +256,8 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) int new_diff=0; + bool updated = m_time_ready; + if ( m_time_ready ) // ref time ready? { // difference between reference time (current enigma time) @@ -268,7 +286,7 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) time_t rtc=getRTC(); m_timeOffsetMap[chan->getChannelID()] = rtc-tp_time; new_diff = rtc-nowTime; // set enigma time to rtc - eDebug("[eDVBLocalTimerHandler] update stored correction to %d (calced against RTC time)", rtc-tp_time ); + eDebug("[eDVBLocalTimerHandler] update stored correction to %ld (calced against RTC time)", rtc-tp_time ); } else if ( abs(ddiff) <= 120 ) { @@ -306,13 +324,15 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) time_t t = nowTime+new_diff; m_last_tp_time_difference=tp_time-t; - if (!new_diff) + if (!new_diff && + updated) // overrride this check on first received TDT { eDebug("[eDVBLocalTimerHandler] not changed"); return; } - tm now = *localtime(&t); + tm now; + localtime_r(&t, &now); eDebug("[eDVBLocalTimerHandler] time update to %02d:%02d:%02d", now.tm_hour, now.tm_min, @@ -322,7 +342,15 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) eDebug("[eDVBLocalTimerHandler] m_time_difference is %d", m_time_difference ); // if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 ) TODO !! + if ( !update_count ) + { + // set rtc to calced transponder time when the first tdt is received on this + // transponder setRTC(t); + eDebug("[eDVBLocalTimerHandler] update RTC"); + } + else + eDebug("[eDVBLocalTimerHandler] don't update RTC"); if ( abs(m_time_difference) > 59 ) { @@ -331,9 +359,7 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) gettimeofday(&tnow,0); tnow.tv_sec=t; settimeofday(&tnow,0); - for (ePtrList::iterator it(eMainloop::existing_loops) - ;it != eMainloop::existing_loops.end(); ++it) - it->setTimerOffset(m_time_difference); + eMainloop::addTimeOffset(m_time_difference); m_time_difference=0; } @@ -346,9 +372,10 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan ) m_knownChannels.find(chan); if ( it != m_knownChannels.end() ) { - delete it->second.tdt; - it->second.tdt = new TDT(chan); + TDT *prev_tdt = it->second.tdt; + it->second.tdt = new TDT(chan, prev_tdt->getUpdateCount()); it->second.tdt->startTimer(60*60*1000); // restart TDT for this transponder in 60min + delete prev_tdt; } } } @@ -357,11 +384,12 @@ void eDVBLocalTimeHandler::DVBChannelAdded(eDVBChannel *chan) { if ( chan ) { - eDebug("[eDVBLocalTimerHandler] add channel %p", chan); +// eDebug("[eDVBLocalTimerHandler] add channel %p", chan); std::pair::iterator, bool> tmp = m_knownChannels.insert( std::pair(chan, channel_data()) ); - tmp.first->second.tdt = new TDT(chan); + tmp.first->second.tdt = NULL; tmp.first->second.channel = chan; + tmp.first->second.m_prevChannelState = -1; chan->connectStateChange(slot(*this, &eDVBLocalTimeHandler::DVBChannelStateChanged), tmp.first->second.m_stateChangedConn); } } @@ -374,23 +402,24 @@ void eDVBLocalTimeHandler::DVBChannelStateChanged(iDVBChannel *chan) { int state=0; chan->getState(state); - switch (state) + if ( state != it->second.m_prevChannelState ) { - case iDVBChannel::state_idle: - break; - case iDVBChannel::state_tuning: - break; - case iDVBChannel::state_unavailable: - break; - case iDVBChannel::state_ok: - eDebug("[eDVBLocalTimerHandler] channel %p running", chan); - it->second.tdt->start(); - break; - case iDVBChannel::state_release: - eDebug("[eDVBLocalTimerHandler] remove channel %p", chan); - delete it->second.tdt; - m_knownChannels.erase(it); - break; + switch (state) + { + case iDVBChannel::state_ok: + eDebug("[eDVBLocalTimerHandler] channel %p running", chan); + it->second.tdt = new TDT(it->second.channel); + it->second.tdt->start(); + break; + case iDVBChannel::state_release: + eDebug("[eDVBLocalTimerHandler] remove channel %p", chan); + delete it->second.tdt; + m_knownChannels.erase(it); + break; + default: // ignore all other events + return; + } + it->second.m_prevChannelState = state; } } }