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)
if ( data && data[0] == 0x70 || data[0] == 0x73 )
{
int length = ((data[1] & 0x0F) << 8) | data[2];
- if ( length >= 8 )
+ 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;
}
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 |
}
}
-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)
{
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");
gettimeofday(&tnow,0);
tnow.tv_sec=rtc_time;
settimeofday(&tnow,0);
- for (ePtrList<eMainloop>::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 )
int new_diff=0;
+ bool updated = m_time_ready;
+
if ( m_time_ready ) // ref time ready?
{
// difference between reference time (current enigma time)
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 )
{
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,
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 )
{
gettimeofday(&tnow,0);
tnow.tv_sec=t;
settimeofday(&tnow,0);
- for (ePtrList<eMainloop>::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;
}
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;
}
}
}
{
if ( chan )
{
- eDebug("[eDVBLocalTimerHandler] add channel %p", chan);
+// eDebug("[eDVBLocalTimerHandler] add channel %p", chan);
std::pair<std::map<iDVBChannel*, channel_data>::iterator, bool> tmp =
m_knownChannels.insert( std::pair<iDVBChannel*, channel_data>(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);
}
}
{
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;
}
}
}