Update EPG Cache(thanks to open source community)
[vuplus_dvbapp] / lib / dvb / dvbtime.cpp
index 89650f2..2db7c8e 100644 (file)
@@ -20,7 +20,7 @@ void setRTC(time_t time)
        FILE *f = fopen("/proc/stb/fp/rtc", "w");
        if (f)
        {
-               if (fprintf(f, "%u", time))
+               if (fprintf(f, "%u", (unsigned int)time))
                        prev_time = time;
                else
                        eDebug("write /proc/stb/fp/rtc failed (%m)");
@@ -47,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
@@ -64,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);
@@ -83,7 +81,39 @@ 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);
 }
 
@@ -103,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;
@@ -145,7 +175,7 @@ eDVBLocalTimeHandler *eDVBLocalTimeHandler::instance;
 DEFINE_REF(eDVBLocalTimeHandler);
 
 eDVBLocalTimeHandler::eDVBLocalTimeHandler()
-       :m_updateNonTunedTimer(eTimer::create(eApp)), m_time_ready(false)
+       :m_use_dvb_time(false), m_updateNonTunedTimer(eTimer::create(eApp)), m_time_ready(false)
 {
        if ( !instance )
                instance=this;
@@ -214,6 +244,33 @@ 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<iDVBChannel*, channel_data>::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<iDVBChannel*, channel_data>::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);
@@ -229,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();
@@ -440,8 +494,10 @@ void eDVBLocalTimeHandler::DVBChannelStateChanged(iDVBChannel *chan)
                                case iDVBChannel::state_ok:
                                        eDebug("[eDVBLocalTimerHandler] channel %p running", chan);
                                        m_updateNonTunedTimer->stop();
-                                       it->second.tdt = new TDT(it->second.channel);
-                                       it->second.tdt->start();
+                                       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);