X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=lib%2Fdvb%2Fdvbtime.cpp;h=2db7c8e1cd45627aa1c9836e386557e6958d5a21;hb=5e0c1dbc3610b703f59fa798748b1676c0f356cc;hp=6cfaccc89f06d213638157d2a3d13a2043a7b384;hpb=92362f1b73f1e61ad0cb1c581b318b360e0bb6fe;p=vuplus_dvbapp diff --git a/lib/dvb/dvbtime.cpp b/lib/dvb/dvbtime.cpp index 6cfaccc..2db7c8e 100644 --- a/lib/dvb/dvbtime.cpp +++ b/lib/dvb/dvbtime.cpp @@ -11,6 +11,8 @@ #define FP_IOCTL_SET_RTC 0x101 #define FP_IOCTL_GET_RTC 0x102 +#define TIME_UPDATE_INTERVAL (30*60*1000) + static time_t prev_time; void setRTC(time_t time) @@ -18,23 +20,11 @@ void setRTC(time_t time) FILE *f = fopen("/proc/stb/fp/rtc", "w"); if (f) { - time_t wakeup=0; - FILE *f2 = fopen("/proc/stb/fp/wakeup_time", "r"); - if (f2) - { - fscanf(f2, "%u", &wakeup); - fclose(f2); - } - if (wakeup) // atmel firmware okay? - { - if (fprintf(f, "%u", time)) - prev_time = time; - else - eDebug("write /proc/stb/fp/rtc failed (%m)"); - fclose(f); - } + if (fprintf(f, "%u", (unsigned int)time)) + prev_time = time; else - eDebug("dont set rtc because of buggy atmel firmware!"); + eDebug("write /proc/stb/fp/rtc failed (%m)"); + fclose(f); } else { @@ -57,8 +47,11 @@ time_t getRTC() if (f) { // sanity check to detect corrupt atmel firmware - if (fscanf(f, "%u", &rtc_time) != 1) + unsigned int tmp; + if (fscanf(f, "%u", &tmp) != 1) eDebug("read /proc/stb/fp/rtc failed (%m)"); + else + rtc_time=tmp; fclose(f); } else @@ -74,13 +67,8 @@ time_t getRTC() return rtc_time != prev_time ? rtc_time : 0; } -time_t parseDVBtime(__u8 t1, __u8 t2, __u8 t3, __u8 t4, __u8 t5) +static void parseDVBdate(tm& t, int mjd) { - tm t; - t.tm_sec=fromBCD(t5); - t.tm_min=fromBCD(t4); - t.tm_hour=fromBCD(t3); - int mjd=(t1<<8)|t2; int k; t.tm_year = (int) ((mjd - 15078.2) / 365.25); @@ -93,15 +81,47 @@ time_t parseDVBtime(__u8 t1, __u8 t2, __u8 t3, __u8 t4, __u8 t5) t.tm_isdst = 0; t.tm_gmtoff = 0; +} + +static inline void parseDVBtime_impl(tm& t, const uint8_t *data) +{ + parseDVBdate(t, (data[0] << 8) | data[1]); + t.tm_hour = fromBCD(data[2]); + t.tm_min = fromBCD(data[3]); + t.tm_sec = fromBCD(data[4]); +} + +time_t parseDVBtime(uint16_t mjd, uint32_t stime_bcd) +{ + tm t; + parseDVBdate(t, mjd); + t.tm_hour = fromBCD(stime_bcd >> 16); + t.tm_min = fromBCD((stime_bcd >> 8)&0xFF); + t.tm_sec = fromBCD(stime_bcd & 0xFF); + return timegm(&t); +} + +time_t parseDVBtime(const uint8_t *data) +{ + tm t; + parseDVBtime_impl(t, data); + return timegm(&t); +} +time_t parseDVBtime(const uint8_t *data, uint16_t *hash) +{ + tm t; + parseDVBtime_impl(t, data); + *hash = t.tm_hour * 60 + t.tm_min; + *hash |= t.tm_mday << 11; return timegm(&t); } TDT::TDT(eDVBChannel *chan, int update_count) - :chan(chan), update_count(update_count) + :chan(chan), m_interval_timer(eTimer::create()), update_count(update_count) { CONNECT(tableReady, TDT::ready); - CONNECT(m_interval_timer.timeout, TDT::start); + CONNECT(m_interval_timer->timeout, TDT::start); if (chan) chan->getDemux(demux, 0); } @@ -113,12 +133,12 @@ void TDT::ready(int error) int TDT::createTable(unsigned int nr, const __u8 *data, unsigned int max) { - if ( data && data[0] == 0x70 || data[0] == 0x73 ) + if ( data && (data[0] == 0x70 || data[0] == 0x73 )) { int length = ((data[1] & 0x0F) << 8) | data[2]; if ( length >= 5 ) { - time_t tptime = parseDVBtime(data[3], data[4], data[5], data[6], data[7]); + time_t tptime = parseDVBtime(&data[3]); if (tptime && tptime != -1) eDVBLocalTimeHandler::getInstance()->updateTime(tptime, chan, update_count); error=0; @@ -148,14 +168,14 @@ void TDT::start() void TDT::startTimer( int interval ) { - m_interval_timer.start(interval, true); + m_interval_timer->start(interval, true); } eDVBLocalTimeHandler *eDVBLocalTimeHandler::instance; DEFINE_REF(eDVBLocalTimeHandler); eDVBLocalTimeHandler::eDVBLocalTimeHandler() - :m_time_ready(false) + :m_use_dvb_time(false), m_updateNonTunedTimer(eTimer::create(eApp)), m_time_ready(false) { if ( !instance ) instance=this; @@ -176,13 +196,12 @@ eDVBLocalTimeHandler::eDVBLocalTimeHandler() /*emit*/ m_timeUpdated(); } } + CONNECT(m_updateNonTunedTimer->timeout, eDVBLocalTimeHandler::updateNonTuned); } 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"); @@ -225,6 +244,39 @@ void eDVBLocalTimeHandler::writeTimeOffsetData( const char* filename ) } } +void eDVBLocalTimeHandler::setUseDVBTime(bool b) +{ + if (m_use_dvb_time != b) { + if (m_use_dvb_time) { + eDebug("[eDVBLocalTimeHandler] disable sync local time with transponder time!"); + std::map::iterator it = + m_knownChannels.begin(); + for (; it != m_knownChannels.end(); ++it) { + if (it->second.m_prevChannelState == iDVBChannel::state_ok) + it->second.tdt = 0; + } + } + else { + eDebug("[eDVBLocalTimeHandler] enable sync local time with transponder time!"); + std::map::iterator it = + m_knownChannels.begin(); + for (; it != m_knownChannels.end(); ++it) { + if (it->second.m_prevChannelState == iDVBChannel::state_ok) { + it->second.tdt = new TDT(it->second.channel); + it->second.tdt->start(); + } + } + } + m_use_dvb_time = b; + } +} + +void eDVBLocalTimeHandler::updateNonTuned() +{ + updateTime(-1, 0, 0); + m_updateNonTunedTimer->start(TIME_UPDATE_INTERVAL, true); +} + void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int update_count ) { int time_difference; @@ -234,9 +286,6 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int up else if (tp_time == -1) { restart_tdt = true; - /*if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 || - ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7000 - && eSystemInfo::getInstance()->hasStandbyWakeupTimer() ) ) TODO !!!!!!! */ { eDebug("[eDVBLocalTimerHandler] no transponder tuned... or no TDT/TOT avail .. try to use RTC :)"); time_t rtc_time = getRTC(); @@ -408,10 +457,10 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int up m_knownChannels.find(chan); if ( it != m_knownChannels.end() ) { - 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; + int updateCount = it->second.tdt->getUpdateCount(); + it->second.tdt = 0; + it->second.tdt = new TDT(chan, updateCount); + it->second.tdt->startTimer(TIME_UPDATE_INTERVAL); // restart TDT for this transponder in 30min } } } @@ -444,13 +493,17 @@ void eDVBLocalTimeHandler::DVBChannelStateChanged(iDVBChannel *chan) { case iDVBChannel::state_ok: eDebug("[eDVBLocalTimerHandler] channel %p running", chan); - it->second.tdt = new TDT(it->second.channel); - it->second.tdt->start(); + m_updateNonTunedTimer->stop(); + if (m_use_dvb_time) { + 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); + if (m_knownChannels.empty()) + m_updateNonTunedTimer->start(TIME_UPDATE_INTERVAL, true); break; default: // ignore all other events return;