42a056d285fd3a6ec8548d32bce3e99cd0ad65b0
[enigma2.git] / lib / dvb / esection.cpp
1 #include <lib/dvb/esection.h>
2 #include <lib/base/eerror.h>
3
4 void eGTable::sectionRead(const __u8 *d)
5 {
6         unsigned int last_section_number = d[7];
7         m_table.flags &= ~eDVBTableSpec::tfAnyVersion;
8         m_table.flags |= eDVBTableSpec::tfThisVersion;
9         m_table.version = (d[5]>>1)&0x1F;
10
11
12         if (createTable(d[6], d, last_section_number + 1))
13         {
14                 if (m_timeout)
15                         m_timeout->stop();
16                 m_reader->stop();
17                 ready = 1;
18                 tableReady(error);
19         } else if ((m_table.flags & eDVBTableSpec::tfHaveTimeout) && m_timeout)
20                 m_timeout->start(m_table.timeout, 1); // reset timeout
21 }
22
23 void eGTable::timeout()
24 {
25         eDebug("timeout!");
26         m_reader->stop();
27         ready = 1;
28         error = -1;
29         tableReady(error);
30 }
31
32 eGTable::eGTable():
33                 m_timeout(0), error(0)
34 {
35 }
36
37 DEFINE_REF(eGTable);
38
39 RESULT eGTable::start(iDVBSectionReader *reader, const eDVBTableSpec &table)
40 {
41         RESULT res;
42         m_table = table;
43
44         m_reader = reader;
45         m_reader->connectRead(slot(*this, &eGTable::sectionRead), m_sectionRead_conn);
46         
47         // setup filter struct
48         eDVBSectionFilterMask mask;
49         
50         memset(&mask, 0, sizeof(mask));
51         mask.pid   = m_table.pid;
52         mask.flags = 0;
53         
54         if (m_table.flags & eDVBTableSpec::tfCheckCRC)
55                 mask.flags |= eDVBSectionFilterMask::rfCRC;
56         
57         if (m_table.flags & eDVBTableSpec::tfHaveTID)
58         {
59                 mask.data[0] = m_table.tid;
60                 mask.mask[0] = 0xFF;
61         }
62         
63         if (m_table.flags & eDVBTableSpec::tfHaveTIDExt)
64         {
65                 mask.data[1] = m_table.tidext >> 8;
66                 mask.data[2] = m_table.tidext;
67                 mask.mask[1] = 0xFF;
68                 mask.mask[2] = 0xFF;
69         }
70         
71         if (!(m_table.flags & eDVBTableSpec::tfAnyVersion))
72         {
73                 eDebug("doing version filtering");
74                 mask.data[3] |= (m_table.version << 1)|1;
75                 mask.mask[3] |= 0x3f;
76                 if (!(m_table.flags & eDVBTableSpec::tfThisVersion))
77                         mask.mode[3] |= 0x3e; // negative filtering
78         } else
79                 eDebug("no version filtering");
80         
81         eDebug("%04x:  %02x %02x %02x %02x %02x %02x",
82                 mask.pid,
83                 mask.data[0], mask.data[1], mask.data[2],
84                 mask.data[3], mask.data[4], mask.data[5]);
85         eDebug("mask:  %02x %02x %02x %02x %02x %02x",
86                 mask.mask[0], mask.mask[1], mask.mask[2],
87                 mask.mask[3], mask.mask[4], mask.mask[5]);
88         eDebug("mode:  %02x %02x %02x %02x %02x %02x",
89                 mask.mode[0], mask.mode[1], mask.mode[2],
90                 mask.mode[3], mask.mode[4], mask.mode[5]);
91
92         if ((res = m_reader->start(mask)))
93         {
94                 eDebug("reader failed to start.");
95                 return res;
96         }
97         
98         if (m_table.flags & eDVBTableSpec::tfHaveTimeout)
99         {
100                 eDebug("have timeout, %d", m_table.timeout);
101                 if (m_timeout)
102                         delete m_timeout;
103                 m_timeout = new eTimer(eApp);
104                 m_timeout->start(m_table.timeout, 1); // begin timeout
105                 CONNECT(m_timeout->timeout, eGTable::timeout);
106         }
107         
108         return 0;
109 }
110
111 RESULT eGTable::start(iDVBDemux *demux, const eDVBTableSpec &table)
112 {
113         int res;
114         ePtr<iDVBSectionReader> reader;
115         res = demux->createSectionReader(eApp, reader);
116         if (res)
117                 return res;
118         return start(reader, table);
119 }
120
121 eGTable::~eGTable()
122 {
123         if (m_timeout)
124                 delete m_timeout;
125 }
126
127 void eAUGTable::slotTableReady(int error)
128 {
129         getNext(error);
130 }