immediate close no more used demux fd's
[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                 /* if a section is missing, we retry reading the
12                    whole data up to 5 times. if after that the
13                    section is still missing, we timeout. */
14         if (m_tries > 5 * (last_section_number+1))
15         {
16                 timeout();
17                 return;
18         }
19         
20         m_tries++;
21
22         if (createTable(d[6], d, last_section_number + 1))
23         {
24                 if (m_timeout)
25                         m_timeout->stop();
26                 m_reader->stop();
27                 m_reader=0;
28                 m_sectionRead_conn=0;
29                 ready = 1;
30                 tableReady(error);
31         } else if ((m_table.flags & eDVBTableSpec::tfHaveTimeout) && m_timeout)
32                 m_timeout->start(m_table.timeout, 1); // reset timeout
33 }
34
35 void eGTable::timeout()
36 {
37         eDebug("timeout!");
38         m_reader->stop();
39         m_reader=0;
40         m_sectionRead_conn=0;
41         ready = 1;
42         error = -1;
43         tableReady(error);
44 }
45
46 eGTable::eGTable():
47                 m_timeout(0), error(0)
48 {
49 }
50
51 DEFINE_REF(eGTable);
52
53 RESULT eGTable::start(iDVBSectionReader *reader, const eDVBTableSpec &table)
54 {
55         RESULT res;
56         m_table = table;
57
58         m_reader = reader;
59         m_reader->connectRead(slot(*this, &eGTable::sectionRead), m_sectionRead_conn);
60         
61         m_tries = 0;
62         
63         // setup filter struct
64         eDVBSectionFilterMask mask;
65         
66         memset(&mask, 0, sizeof(mask));
67         mask.pid   = m_table.pid;
68         mask.flags = 0;
69         
70         if (m_table.flags & eDVBTableSpec::tfCheckCRC)
71                 mask.flags |= eDVBSectionFilterMask::rfCRC;
72         
73         if (m_table.flags & eDVBTableSpec::tfHaveTID)
74         {
75                 mask.data[0] = m_table.tid;
76                 if (m_table.flags & eDVBTableSpec::tfHaveTIDMask)
77                         mask.mask[0] = m_table.tid_mask;
78                 else
79                         mask.mask[0] = 0xFF;
80         }
81
82         if (m_table.flags & eDVBTableSpec::tfHaveTIDExt)
83         {
84                 mask.data[1] = m_table.tidext >> 8;
85                 mask.data[2] = m_table.tidext;
86                 if (m_table.flags & eDVBTableSpec::tfHaveTIDExtMask)
87                 {
88                         mask.mask[1] = m_table.tidext_mask >> 8;
89                         mask.mask[2] = m_table.tidext_mask;
90                 }
91                 else
92                 {
93                         mask.mask[1] = 0xFF;
94                         mask.mask[2] = 0xFF;
95                 }
96         }
97         
98         if (!(m_table.flags & eDVBTableSpec::tfAnyVersion))
99         {
100                 eDebug("doing version filtering");
101                 mask.data[3] |= (m_table.version << 1)|1;
102                 mask.mask[3] |= 0x3f;
103                 if (!(m_table.flags & eDVBTableSpec::tfThisVersion))
104                         mask.mode[3] |= 0x3e; // negative filtering
105         } else
106                 eDebug("no version filtering");
107         
108         eDebug("%04x:  %02x %02x %02x %02x %02x %02x",
109                 mask.pid,
110                 mask.data[0], mask.data[1], mask.data[2],
111                 mask.data[3], mask.data[4], mask.data[5]);
112         eDebug("mask:  %02x %02x %02x %02x %02x %02x",
113                 mask.mask[0], mask.mask[1], mask.mask[2],
114                 mask.mask[3], mask.mask[4], mask.mask[5]);
115         eDebug("mode:  %02x %02x %02x %02x %02x %02x",
116                 mask.mode[0], mask.mode[1], mask.mode[2],
117                 mask.mode[3], mask.mode[4], mask.mode[5]);
118
119         if ((res = m_reader->start(mask)))
120         {
121                 eDebug("reader failed to start.");
122                 return res;
123         }
124         
125         if (m_table.flags & eDVBTableSpec::tfHaveTimeout)
126         {
127                 if (m_timeout)
128                         delete m_timeout;
129                 m_timeout = new eTimer(eApp);
130                 m_timeout->start(m_table.timeout, 1); // begin timeout
131                 CONNECT(m_timeout->timeout, eGTable::timeout);
132         }
133         
134         return 0;
135 }
136
137 RESULT eGTable::start(iDVBDemux *demux, const eDVBTableSpec &table)
138 {
139         int res;
140         ePtr<iDVBSectionReader> reader;
141         res = demux->createSectionReader(eApp, reader);
142         if (res)
143                 return res;
144         return start(reader, table);
145 }
146
147 eGTable::~eGTable()
148 {
149         if (m_timeout)
150                 delete m_timeout;
151 }
152
153 void eAUGTable::slotTableReady(int error)
154 {
155         getNext(error);
156 }