You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kaffeine/kaffeine/src/input/dvb/plugins/epg/kaffeinedvbsection.cpp

331 lines
7.5 KiB

/*
* kaffeinedvbsection.cpp
*
* Copyright (C) 2003-2007 Christophe Thommeret <hftom@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <time.h>
#include <iconv.h>
#include <tdelocale.h>
#include "kaffeinedvbsection.h"
KaffeineDVBsection::KaffeineDVBsection()
{
}
KaffeineDVBsection::KaffeineDVBsection( int anum, int tnum, const TQString &charset )
{
initSection( anum, tnum, charset );
}
void KaffeineDVBsection::initSection( int anum, int tnum, const TQString &charset )
{
defaultCharset = charset.ascii();
adapter = anum;
tuner = tnum;
isRunning = false;
fdDemux = -1;
}
KaffeineDVBsection::~KaffeineDVBsection()
{
if ( fdDemux>-1 )
close( fdDemux );
}
bool KaffeineDVBsection::setFilter( int pid, int tid, int timeout, bool checkcrc )
{
struct dmx_sct_filter_params sctfilter;
TQString demuxer = TQString("/dev/dvb/adapter%1/demux%2").arg( adapter ).arg( tuner );
if ((fdDemux = open( demuxer.ascii(), O_RDWR | O_NONBLOCK )) < 0) {
perror ("open failed");
return false;
}
pf[0].fd = fdDemux;
pf[0].events = POLLIN;
memset( &sctfilter, 0, sizeof( sctfilter ) );
sctfilter.pid = pid;
if ( tid<256 && tid>0 ) {
sctfilter.filter.filter[0] = tid;
sctfilter.filter.mask[0] = 0xff;
}
sctfilter.flags = DMX_IMMEDIATE_START;
if ( checkcrc )
sctfilter.flags|= DMX_CHECK_CRC;
sctfilter.timeout = timeout;
if ( ioctl( fdDemux, DMX_SET_FILTER, &sctfilter ) < 0 ) {
perror ( "ioctl DMX_SET_FILTER failed" );
return false;
}
return true;
}
void KaffeineDVBsection::stopFilter()
{
ioctl( fdDemux, DMX_STOP );
close( fdDemux );
fdDemux = -1;
}
unsigned int KaffeineDVBsection::getBits( unsigned char *b, int offbits, int nbits )
{
int i, nbytes;
unsigned int ret = 0;
unsigned char *buf;
buf = b+(offbits/8);
offbits %=8;
nbytes = (offbits+nbits)/8;
if ( ((offbits+nbits)%8)>0 )
nbytes++;
for ( i=0; i<nbytes; i++ )
ret += buf[i]<<((nbytes-i-1)*8);
i = (4-nbytes)*8+offbits;
ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-offbits);
return ret;
}
bool KaffeineDVBsection::doIconv( TQCString &s, TQCString table, char *buffer, int buflen )
{
size_t inSize, outSize=buflen;
char *inBuf, *outBuf;
iconv_t cd;
inSize = s.length();
if ( inSize<1 )
return false;
cd = iconv_open( "UTF8", table );
//check if charset unknown
if( cd == (iconv_t)(-1) )
return false;
inBuf = s.data();
outBuf = buffer;
outBuf[0] = 0;
iconv( cd, &inBuf, &inSize, &outBuf, &outSize );
*outBuf = 0;
iconv_close( cd );
return true;
}
TQString KaffeineDVBsection::getText( unsigned char *buf, int length )
{
TQCString s;
TQString ret="";
int i=0;
char buffer[1000];
TQCString table=defaultCharset;
if ( length==0 )
return "";
while ( i<length ) {
if ( buf[i]<0x20 && (i+2)<length ) {
if ( !s.isEmpty() ) {
if ( doIconv( s, table, buffer, sizeof(buffer) ) ) {
ret += TQString::fromUtf8( buffer );
s = "";
}
}
switch ( buf[i] ) {
case 0x01: table = "ISO8859-5"; ++i; break;
case 0x02: table = "ISO8859-6"; ++i; break;
case 0x03: table = "ISO8859-7"; ++i; break;
case 0x04: table = "ISO8859-8"; ++i; break;
case 0x05: table = "ISO8859-9"; ++i; break;
case 0x06: table = "ISO8859-10"; ++i; break;
case 0x07: table = "ISO8859-11"; ++i; break;
case 0x09: table = "ISO8859-13"; ++i; break;
case 0x0A: table = "ISO8859-14"; ++i; break;
case 0x0B: table = "ISO8859-15"; ++i; break;
case 0x13: table = "GB2312"; ++i; break;
case 0x14: table = "BIG5"; ++i; break;
case 0x10: {
switch ( buf[i+2] ) {
case 0x01: table = "ISO8859-1"; break;
case 0x02: table = "ISO8859-2"; break;
case 0x03: table = "ISO8859-3"; break;
case 0x04: table = "ISO8859-4"; break;
case 0x05: table = "ISO8859-5"; break;
case 0x06: table = "ISO8859-6"; break;
case 0x07: table = "ISO8859-7"; break;
case 0x08: table = "ISO8859-8"; break;
case 0x09: table = "ISO8859-9"; break;
case 0x0A: table = "ISO8859-10"; break;
case 0x0B: table = "ISO8859-11"; break;
case 0x0D: table = "ISO8859-13"; break;
case 0x0E: table = "ISO8859-14"; break;
case 0x0F: table = "ISO8859-15"; break;
}
i+= 3;
break;
}
default: ++i;
}
}
if ( buf[i]>=0x80 && buf[i]<=0x9f ) {
++i;
continue; // control codes
}
s += buf[i++];
}
if ( !s.isEmpty() ) {
if ( doIconv( s, table, buffer, sizeof(buffer) ) ) {
ret += TQString::fromUtf8( buffer );
}
}
return ret;
}
TQString KaffeineDVBsection::langDesc( unsigned char* buf )
{
char c[4];
TQString s;
memset( mempcpy( c, buf+2, 3 ), 0, 1 );
s = c;
return s;
}
TQTime KaffeineDVBsection::getTime( unsigned char *buf )
{
int h, m, s;
h = ((getBits(buf,0,4)*10)+getBits(buf,4,4))%24;
m = ((getBits(buf,8,4)*10)+getBits(buf,12,4))%60;
s = ((getBits(buf,16,4)*10)+getBits(buf,20,4))%60;
return TQTime( h, m, s );
}
TQDate KaffeineDVBsection::getDate( unsigned char *buf )
{
int i, j, m, D, Y, M, k, mjd;
mjd = getBits(buf,0,16);
i = (int)((mjd-15078.2)/365.25);
j = (int)(i*365.25);
m = (int)((mjd-14956.1-j)/30.6001);
D = mjd-14956-j-(int)(m*30.6001);
if ( m==14 || m==15 )
k = 1;
else
k = 0;
Y = i+k+1900;
M = m-1-k*12;
return TQDate( (Y>=1970)?Y:1970, (M>0 && M<13)?M:1, (D>0 && D<32)?D:1 );
}
TQDateTime KaffeineDVBsection::getDateTime( unsigned char *buf )
{
/*int hh, mm, ss;
int i, j, m, D, Y, M, k, mjd;
int sec;
mjd = getBits(buf,0,16);
i = (int)((mjd-15078.2)/365.25);
j = (int)(i*365.25);
m = (int)((mjd-14956.1-j)/30.6001);
D = mjd-14956-j-(int)(m*30.6001);
if ( m==14 || m==15 ) k = 1;
else k = 0;
Y = i+k+1900;
M = m-1-k*12;
hh = ((getBits(buf+2,0,4)*10)+getBits(buf+2,4,4))%24;
mm = ((getBits(buf+2,8,4)*10)+getBits(buf+2,12,4))%60;
ss = ((getBits(buf+2,16,4)*10)+getBits(buf+2,20,4))%60;
TQDateTime dt( TQDate( (Y>=1970)?Y:1970, (M>0 && M<13)?M:1, (D>0 && D<32)?D:1 ), TQTime( hh, mm, ss ) );
TQDateTime u( TQDate( 1970, 1, 1 ), TQTime( 0, 0, 0 ) );
sec = u.secsTo( dt );
u.setTime_t( sec ); // UTC to local
return u;*/
int i, j, m, k, mjd;
struct tm tt;
struct tm *t=&tt;
mjd = getBits(buf,0,16);
i = (int)((mjd-15078.2)/365.25);
j = (int)(i*365.25);
m = (int)((mjd-14956.1-j)/30.6001);
t->tm_mday = mjd-14956-j-(int)(m*30.6001);
if ( m==14 || m==15 )
k = 1;
else
k = 0;
t->tm_year = i+k;
t->tm_mon = m-1-k*12-1;
t->tm_sec = ((getBits(buf+2,16,4)*10)+getBits(buf+2,20,4))%60;
t->tm_min = ((getBits(buf+2,8,4)*10)+getBits(buf+2,12,4))%60;
t->tm_hour = ((getBits(buf+2,0,4)*10)+getBits(buf+2,4,4))%24;
t->tm_isdst = -1;
t->tm_gmtoff = 0;
time_t p=timegm(t);
if ( p>0 ) {
t = localtime(&p);
return TQDateTime( TQDate( t->tm_year+1900, t->tm_mon+1, t->tm_mday ), TQTime( t->tm_hour, t->tm_min, t->tm_sec ) );
}
else
return TQDateTime( TQDate( 1970, 1, 1 ), TQTime( 0, 0, 0 ) );
}