1 #include <lib/dvb/esection.h>
10 #include <sys/ioctl.h>
12 #include <lib/base/ebase.h>
13 #include <lib/base/eerror.h>
14 #include <lib/system/elock.h>
15 #include <lib/system/info.h>
17 #if HAVE_DVB_API_VERSION < 3
20 #include <linux/dvb/dmx.h>
23 static pthread_mutex_t slock
=
24 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
;
25 ePtrList
<eSection
> eSection::active
;
27 eSectionReader::eSectionReader()
32 int eSectionReader::getHandle()
37 void eSectionReader::close()
44 int eSectionReader::open(int pid
, __u8
*data
, __u8
*mask
, __u8
*mode
, int len
, int _flags
, const char* dmxdev
)
49 #if HAVE_DVB_API_VERSION < 3
50 dmxSctFilterParams secFilterParams
;
52 dmx_sct_filter_params secFilterParams
;
57 handle
=::open(dmxdev
, O_RDWR
|O_NONBLOCK
);
58 // eDebug("opened handle %d", handle);
64 #if HAVE_DVB_API_VERSION == 3
67 if (::ioctl(handle
, DMX_SET_BUFFER_SIZE
, 128*1024) < 0 )
68 eDebug("DMX_SET_BUFFER_SIZE failed (%m)");
72 secFilterParams
.pid
=pid
;
74 #if HAVE_DVB_API_VERSION < 3
75 memset(secFilterParams
.filter
.filter
, 0, DMX_FILTER_SIZE
);
76 memset(secFilterParams
.filter
.mask
, 0, DMX_FILTER_SIZE
);
78 memset(&secFilterParams
.filter
, 0, sizeof(struct dmx_filter
));
81 secFilterParams
.timeout
=0;
82 secFilterParams
.flags
=DMX_IMMEDIATE_START
;
83 #if HAVE_DVB_API_VERSION < 3
84 if ( eSystemInfo::getInstance()->hasNegFilter() )
85 secFilterParams
.flags
=0;
87 if (flags
&SECREAD_CRC
)
88 secFilterParams
.flags
|=DMX_CHECK_CRC
;
89 for (int i
= 0; i
< len
; i
++)
91 secFilterParams
.filter
.filter
[i
]=data
[i
];
92 secFilterParams
.filter
.mask
[i
]=mask
[i
];
93 #if HAVE_DVB_API_VERSION >= 3
94 secFilterParams
.filter
.mode
[i
]=mode
[i
];
99 eDebugNoNewLine("%02x: ", pid
);
100 for (int i
=0; i
<DMX_FILTER_SIZE
; i
++)
101 eDebugNoNewLine("%02x ", secFilterParams
.filter
.filter
[i
]);
102 eDebugNoNewLine(" (napi)\n ");
103 for (int i
=0; i
<DMX_FILTER_SIZE
; i
++)
104 eDebugNoNewLine("%02x ", secFilterParams
.filter
.mask
[i
]);
108 if (ioctl(handle
, DMX_SET_FILTER
, &secFilterParams
) < 0)
110 perror("DMX_SET_FILTER\n");
115 #if HAVE_DVB_API_VERSION < 3
116 if ( eSystemInfo::getInstance()->hasNegFilter() )
118 __u8 negfilter
[DMX_FILTER_SIZE
];
119 memset(negfilter
, 0, DMX_FILTER_SIZE
);
120 memcpy(negfilter
, mode
, len
);
121 if (::ioctl(handle
, DMX_SET_NEGFILTER_MASK
, negfilter
) < 0)
122 eDebug("DMX_SET_NEGFILTER_MASK (%m)");
123 if (::ioctl(handle
, DMX_START
, 0) < 0)
124 eDebug("DMX_START failed(%m)");
131 int eSectionReader::read(__u8
*buf
)
133 int rd
= ::read(handle
, buf
, 4098);
136 /* backup errno, for instance eDebug could change it */
140 eDebug("section read(%m)");
143 if (rd
> 0 && (buf
[0] & tableid_mask
) != (tableid
& tableid_mask
))
145 eDebug("skip section data.. table_id isn't valid");
152 eFatal("read less then 3 bytes from section.. skip");
155 int seclen
=(buf
[1]&0x0F)<<8;
160 eFatal("cannot read the complete section(%d/%d)",
166 eFatal("read more bytes than section length(%d/%d)",
174 eSection::eSection(int _pid
, int _tableid
, int _tableidext
, int _version
, int _flags
, int _tableidmask
)
175 :context(eApp
), notifier(0), pid(_pid
), tableid(_tableid
)
176 ,tableidext(_tableidext
), tableidmask(_tableidmask
), maxsec(0)
177 ,section(-1), flags(_flags
), timer(0)
178 ,lockcount(0), version(_version
)
184 :context(eApp
), notifier(0), pid(0), tableid(0), tableidext(0)
185 ,tableidmask(0), maxsec(0), section(-1), flags(0)
186 ,timer(0), lockcount(0), version(0)
191 eSection::~eSection()
195 eDebug("deleted still locked table");
200 int eSection::start( const char* dmxdev
)
202 if (timer
&& version
==-1)
204 pid
== 0x14 /* TOT/TDT */ ? 90000 :
205 pid
== 0x10 /* NIT */ ? 12000 :
206 pid
== 0x00 /* PAT */ ? 4000 :
207 pid
== 0x11 /* SDT */ ? 5000 :
208 pid
== 0x12 /* EIT */ ? 15000 :
209 tableid
== 0x02 /* PMT */ ? 4000 : 10000, true);
210 return setFilter(pid
, tableid
, tableidext
, version
, flags
, tableidmask
, dmxdev
);
213 int eSection::setFilter(int pid
, int tableid
, int tableidext
, int version
, int flags
, int tableidmask
, const char *dmxdev
)
216 this->tableid
= tableid
,
217 this->tableidext
= tableidext
;
218 this->version
= version
;
220 this->tableidmask
= tableidmask
;
224 __u8 data
[4], mask
[4], mode
[4];
226 data
[0]=tableid
; mask
[0]=tableidmask
;
227 data
[1]=0; mask
[1]=0;
228 data
[2]=0; mask
[2]=0;
229 data
[3]=0; mask
[3]=0;
232 data
[1]=tableidext
>>8; mask
[1]=0xFF;
233 data
[2]=tableidext
&0xFF; mask
[2]=0xFF;
237 if ( eSystemInfo::getInstance()->hasNegFilter() )
239 data
[3]=version
<<1; mask
[3]=0x3E; mode
[3]=0x3E;
243 data
[3]=version
; mask
[3]=0xFF;
247 reader
.open(pid
, data
, mask
, mode
, 4, flags
, dmxdev
);
248 if (reader
.getHandle() < 0)
251 if (!(flags
&SECREAD_NOABORT
))
254 active
.push_back(this);
257 if ( timer
&& (flags
&SECREAD_NOTIMEOUT
) )
266 notifier
=new eSocketNotifier(context
, reader
.getHandle(), eSocketNotifier::Read
);
268 CONNECT(notifier
->activated
, eSection::data
);
273 void eSection::closeFilter()
275 if (reader
.getHandle()>0)
277 if (!(flags
&SECREAD_NOABORT
))
290 void eSection::data(int socket
)
297 eDebug("eSection::data on locked section!");
299 int ret
= reader
.read(buf
);
308 timer
->start(10000, true);
312 eDebug("section read error %d for pid %04x, tid %02x, tidmask %02x, tidext %04x... restart timeout\n",
313 ret
, pid
, tableid
, tableidmask
, tableidext
);
315 case -2: // internal error table id not correct
317 timer
->start(10000, true);
323 // printf("%d/%d, we want %d | service_id %04x | version %04x\n", buf[6], maxsec, section, (buf[3]<<8)|buf[4], buf[5]);
325 if (flags
&SECREAD_INORDER
)
327 if (section
!= buf
[6])
334 // get new valid data restart timeout
335 int err
=sectionRead(buf
);
345 if ( flags
&SECREAD_INORDER
&& section
> maxsec
)
348 closeFilter(); // stop feeding
353 // when more data to read.. restart timeout..
355 timer
->start(10000,true);
359 void eSection::timeout()
361 eDebug("Section timeout PID %04x", pid
);
363 sectionFinish(-ETIMEDOUT
);
366 int eSection::abort()
368 if (reader
.getHandle()>0)
371 sectionFinish(-ECANCELED
);
377 int eSection::abortAll()
380 for (ePtrList
<eSection
>::iterator
it(active
.begin()); it
!= active
.end();)
382 // abort only sections in main context..
383 if ( it
->context
== eApp
)
395 int eSection::sectionRead(__u8
*data
)
401 void eSection::sectionFinish(int)
410 int eSection::unlock()
415 eDebug("unlocking... but not locked");
419 void eSection::setContext( eMainloop
*context
)
421 this->context
= context
;
424 if ( !(flags
&SECREAD_NOTIMEOUT
) )
426 timer
=new eTimer(context
);
427 CONNECT(timer
->timeout
, eSection::timeout
);
430 eWarning("setContext with running notifier !!!");
433 void eTable::sectionFinish(int err
)
438 /*emit*/ tableReady(error
);
441 eTable::eTable(int pid
, int tableid
, int tableidext
, int version
)
442 :eSection(pid
, tableid
, tableidext
, version
443 ,(pid
==0x14)?0:(SECREAD_INORDER
|SECREAD_CRC
), 0xFF)
448 eTable::eTable(int pid
, int tableid
, int tableidmask
, int tableidext
, int version
)
449 :eSection(pid
, tableid
, tableidext
, version
450 ,(pid
==0x14)?0:(SECREAD_INORDER
|SECREAD_CRC
), tableidmask
)
460 eTable
*eTable::createNext()
465 void eAUGTable::slotTableReady(int error
)