/* * kaffeinedvbsection.cpp * * Copyright (C) 2003-2007 Christophe Thommeret * * 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 #include #include #include #include #include #include #include #include #include #include #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>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=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 ) ); }