Merge branch 'master' of fraxinas@git.opendreambox.org:/git/enigma2
[enigma2.git] / lib / dvb / dvbtime.cpp
index 616363f9107af2400d1da8e6e93ec04adf6a1dcc..c43357959b16165052d86f71acdc3b378aacf45d 100644 (file)
@@ -15,26 +15,49 @@ static time_t prev_time;
 
 void setRTC(time_t time)
 {
-       int fd = open("/dev/dbox/fp0", O_RDWR);
-       if ( fd >= 0 )
+       FILE *f = fopen("/proc/stb/fp/rtc", "w");
+       if (f)
        {
-               if ( ::ioctl(fd, FP_IOCTL_SET_RTC, (void*)&time ) < 0 )
-                       eDebug("FP_IOCTL_SET_RTC failed(%m)");
-               else
+               if (fprintf(f, "%u", time))
                        prev_time = time;
-               close(fd);
+               else
+                       eDebug("write /proc/stb/fp/rtc failed (%m)");
+               fclose(f);
+       }
+       else
+       {
+               int fd = open("/dev/dbox/fp0", O_RDWR);
+               if ( fd >= 0 )
+               {
+                       if ( ::ioctl(fd, FP_IOCTL_SET_RTC, (void*)&time ) < 0 )
+                               eDebug("FP_IOCTL_SET_RTC failed(%m)");
+                       else
+                               prev_time = time;
+                       close(fd);
+               }
        }
 }
 
 time_t getRTC()
 {
        time_t rtc_time=0;
-       int fd = open("/dev/dbox/fp0", O_RDWR);
-       if ( fd >= 0 )
+       FILE *f = fopen("/proc/stb/fp/rtc", "r");
+       if (f)
        {
-               if ( ::ioctl(fd, FP_IOCTL_GET_RTC, (void*)&rtc_time ) < 0 )
-                       eDebug("FP_IOCTL_GET_RTC failed(%m)");
-               close(fd);
+               // sanity check to detect corrupt atmel firmware
+               if (fscanf(f, "%u", &rtc_time) != 1)
+                       eDebug("read /proc/stb/fp/rtc failed (%m)");
+               fclose(f);
+       }
+       else
+       {
+               int fd = open("/dev/dbox/fp0", O_RDWR);
+               if ( fd >= 0 )
+               {
+                       if ( ::ioctl(fd, FP_IOCTL_GET_RTC, (void*)&rtc_time ) < 0 )
+                               eDebug("FP_IOCTL_GET_RTC failed(%m)");
+                       close(fd);
+               }
        }
        return rtc_time != prev_time ? rtc_time : 0;
 }
@@ -63,10 +86,10 @@ time_t parseDVBtime(__u8 t1, __u8 t2, __u8 t3, __u8 t4, __u8 t5)
 }
 
 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,7 +136,7 @@ void TDT::start()
 
 void TDT::startTimer( int interval )
 {
-       m_interval_timer.start(interval, true);
+       m_interval_timer->start(interval, true);
 }
 
 eDVBLocalTimeHandler *eDVBLocalTimeHandler::instance;
@@ -146,8 +169,6 @@ eDVBLocalTimeHandler::eDVBLocalTimeHandler()
 eDVBLocalTimeHandler::~eDVBLocalTimeHandler()
 {
        instance=0;
-       for (std::map<iDVBChannel*, channel_data>::iterator it=m_knownChannels.begin(); it != m_knownChannels.end(); ++it)
-               delete it->second.tdt;
        if (ready())
        {
                eDebug("set RTC to previous valid time");
@@ -373,10 +394,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());
+                       int updateCount = it->second.tdt->getUpdateCount();
+                       it->second.tdt = 0;
+                       it->second.tdt = new TDT(chan, updateCount);
                        it->second.tdt->startTimer(60*60*1000);  // restart TDT for this transponder in 60min
-                       delete prev_tdt;
                }
        }
 }
@@ -414,7 +435,6 @@ void eDVBLocalTimeHandler::DVBChannelStateChanged(iDVBChannel *chan)
                                        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