also use refcounting for eTimers
[enigma2.git] / lib / dvb / esection.cpp
index 42a056d285fd3a6ec8548d32bce3e99cd0ad65b0..28e37cbc769de87a5fc0bf703051a681121676dd 100644 (file)
@@ -8,12 +8,27 @@ void eGTable::sectionRead(const __u8 *d)
        m_table.flags |= eDVBTableSpec::tfThisVersion;
        m_table.version = (d[5]>>1)&0x1F;
 
+               /* if a section is missing, we retry reading the
+                  whole data up to 5 times. if after that the
+                  section is still missing, we timeout. */
+       if (m_tries > 5 * (last_section_number+1))
+       {
+               timeout();
+               return;
+       }
+       
+       m_tries++;
 
        if (createTable(d[6], d, last_section_number + 1))
        {
                if (m_timeout)
                        m_timeout->stop();
-               m_reader->stop();
+               if (m_reader)
+               {
+                       m_reader->stop();
+                       m_reader=0;
+               }
+               m_sectionRead_conn=0;
                ready = 1;
                tableReady(error);
        } else if ((m_table.flags & eDVBTableSpec::tfHaveTimeout) && m_timeout)
@@ -22,15 +37,20 @@ void eGTable::sectionRead(const __u8 *d)
 
 void eGTable::timeout()
 {
-       eDebug("timeout!");
-       m_reader->stop();
+       TABLE_eDebug("timeout %04x!", m_table.pid);
+       if (m_reader)
+       {
+               m_reader->stop();
+               m_reader=0;
+       }
+       m_sectionRead_conn=0;
        ready = 1;
        error = -1;
        tableReady(error);
 }
 
-eGTable::eGTable():
-               m_timeout(0), error(0)
+eGTable::eGTable(bool debug):
+               m_debug(debug), error(0)
 {
 }
 
@@ -44,6 +64,8 @@ RESULT eGTable::start(iDVBSectionReader *reader, const eDVBTableSpec &table)
        m_reader = reader;
        m_reader->connectRead(slot(*this, &eGTable::sectionRead), m_sectionRead_conn);
        
+       m_tries = 0;
+       
        // setup filter struct
        eDVBSectionFilterMask mask;
        
@@ -57,50 +79,58 @@ RESULT eGTable::start(iDVBSectionReader *reader, const eDVBTableSpec &table)
        if (m_table.flags & eDVBTableSpec::tfHaveTID)
        {
                mask.data[0] = m_table.tid;
-               mask.mask[0] = 0xFF;
+               if (m_table.flags & eDVBTableSpec::tfHaveTIDMask)
+                       mask.mask[0] = m_table.tid_mask;
+               else
+                       mask.mask[0] = 0xFF;
        }
-       
+
        if (m_table.flags & eDVBTableSpec::tfHaveTIDExt)
        {
                mask.data[1] = m_table.tidext >> 8;
                mask.data[2] = m_table.tidext;
-               mask.mask[1] = 0xFF;
-               mask.mask[2] = 0xFF;
+               if (m_table.flags & eDVBTableSpec::tfHaveTIDExtMask)
+               {
+                       mask.mask[1] = m_table.tidext_mask >> 8;
+                       mask.mask[2] = m_table.tidext_mask;
+               }
+               else
+               {
+                       mask.mask[1] = 0xFF;
+                       mask.mask[2] = 0xFF;
+               }
        }
        
        if (!(m_table.flags & eDVBTableSpec::tfAnyVersion))
        {
-               eDebug("doing version filtering");
+               TABLE_eDebug("doing version filtering");
                mask.data[3] |= (m_table.version << 1)|1;
                mask.mask[3] |= 0x3f;
                if (!(m_table.flags & eDVBTableSpec::tfThisVersion))
                        mask.mode[3] |= 0x3e; // negative filtering
        } else
-               eDebug("no version filtering");
-       
-       eDebug("%04x:  %02x %02x %02x %02x %02x %02x",
+               TABLE_eDebug("no version filtering");
+
+       TABLE_eDebug("%04x:  %02x %02x %02x %02x %02x %02x",
                mask.pid,
                mask.data[0], mask.data[1], mask.data[2],
                mask.data[3], mask.data[4], mask.data[5]);
-       eDebug("mask:  %02x %02x %02x %02x %02x %02x",
+       TABLE_eDebug("mask:  %02x %02x %02x %02x %02x %02x",
                mask.mask[0], mask.mask[1], mask.mask[2],
                mask.mask[3], mask.mask[4], mask.mask[5]);
-       eDebug("mode:  %02x %02x %02x %02x %02x %02x",
+       TABLE_eDebug("mode:  %02x %02x %02x %02x %02x %02x",
                mask.mode[0], mask.mode[1], mask.mode[2],
                mask.mode[3], mask.mode[4], mask.mode[5]);
 
        if ((res = m_reader->start(mask)))
        {
-               eDebug("reader failed to start.");
+               TABLE_eDebug("reader failed to start.");
                return res;
        }
        
        if (m_table.flags & eDVBTableSpec::tfHaveTimeout)
        {
-               eDebug("have timeout, %d", m_table.timeout);
-               if (m_timeout)
-                       delete m_timeout;
-               m_timeout = new eTimer(eApp);
+               m_timeout = eTimer::create(eApp);
                m_timeout->start(m_table.timeout, 1); // begin timeout
                CONNECT(m_timeout->timeout, eGTable::timeout);
        }
@@ -120,8 +150,6 @@ RESULT eGTable::start(iDVBDemux *demux, const eDVBTableSpec &table)
 
 eGTable::~eGTable()
 {
-       if (m_timeout)
-               delete m_timeout;
 }
 
 void eAUGTable::slotTableReady(int error)