Updated Kaffeine to latest upstream version

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kaffeine@1182813 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
v3.5.13-sru
tpearson 15 years ago
parent c1aed14da1
commit d32030ae51

@ -3,6 +3,31 @@
* KAFFEINE ChangeLog *
****************************
0.8.8
* DVB: allow OSD on HD channels.
* DVB: PAT/PMT radios fixes.
* DVB: added live ringbuffer size option (in misc page)
* DVB: added tuner priority option.
* DVB: added mini-Diseqc option.
* DVB: added "Sending diseqc cmds twice" option.
* DVB: added "External positionner" option.
* DVB: option to disable MFE probing.
* DVB: add DVB-S2 support.
* DVB: port to S2API.
* DVB: fixed crash that sometimes occurred during ATSC scanning
* DVB: improve support for ATSC scanning on cable (QAM)
0.8.7
* kaffeine: add MOD/STM mimetypes
* kaffeine: fullscreen fix, patch by Einars Lielmanis <einars@gmail.com>
* DVB: updated libdvb, added CAM menu.
* DVB: added multiservices CAM support.
* DVB: added ATSC scanning, patch by "Devin Heitmueller" <devin.heitmueller@gmail.com>
* DVB: added 7MHz autoscan.
* DVB: reworked CAM support.
0.8.6
* kaffeine: new jpeg logo (the animated one is renamed logo.avi)

@ -1 +1 @@
kaffeine version 0.8.6
kaffeine version 0.8.8

File diff suppressed because it is too large Load Diff

13128
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

@ -40,9 +40,7 @@ dnl Perform program name transformation
AC_ARG_PROGRAM
dnl Automake doc recommends to do this only here. (Janos)
AM_INIT_AUTOMAKE(kaffeine, 0.8.5) dnl searches for some needed programs
AM_MAINTAINER_MODE
AM_INIT_AUTOMAKE(kaffeine-0.8.8, "3.5.7") dnl searches for some needed programs
KDE_SET_PREFIX
@ -66,13 +64,6 @@ dnl FILE: configure.in.in
dnl =======================================================
#MIN_CONFIG(3.3)
KDE_ENABLE_HIDDEN_VISIBILITY
dnl PACKAGE set before
AM_MAINTAINER_MODE
CXXFLAGS="$CXXFLAGS $KDE_DEFAULT_CXXFLAGS"
if test "$build_arts" = "yes"; then
@ -309,7 +300,7 @@ dnl --------------------
dnl check for cdparanoia
dnl --------------------
KDE_CHECK_HEADER([cdda_interface.h], [with_cdparanoia=yes], [with_cdparanoia=no])
KDE_CHECK_HEADER([cdio/cdda.h], [with_cdparanoia=yes], [with_cdparanoia=no])
if test "$with_cdparanoia" != "yes" ; then
echo ""
@ -395,6 +386,7 @@ AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/libdvbapi/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/libdvben50221/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/libucsi/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/libucsi/atsc/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/libucsi/dvb/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/lib/libucsi/mpeg/Makefile ])
AC_CONFIG_FILES([ kaffeine/src/input/dvb/plugins/Makefile ])

@ -1,11 +1,4 @@
#MIN_CONFIG(3.3)
KDE_ENABLE_HIDDEN_VISIBILITY
AM_INIT_AUTOMAKE(kaffeine, 0.8.5)
AM_MAINTAINER_MODE
CXXFLAGS="$CXXFLAGS $KDE_DEFAULT_CXXFLAGS"
if test "$build_arts" = "yes"; then

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 KiB

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

@ -220,7 +220,7 @@ dnl --------------------
dnl check for cdparanoia
dnl --------------------
KDE_CHECK_HEADER([cdda_interface.h], [with_cdparanoia=yes], [with_cdparanoia=no])
KDE_CHECK_HEADER([cdio/cdda.h], [with_cdparanoia=yes], [with_cdparanoia=no])
if test "$with_cdparanoia" != "yes" ; then
echo ""

Binary file not shown.

@ -28,7 +28,7 @@ libkaffeinedisc_la_LDFLAGS = $(KDE_RPATH) \
libkaffeinedisc_la_LIBADD = $(top_builddir)/kaffeine/src/input/libkaffeineinput.la \
$(top_builddir)/kaffeine/src/player-parts/kaffeine-part/libkaffeinepart.la \
$(top_builddir)/kaffeine/src/input/disc/plugins/libkaffeineaudioencoder.la \
-lcdda_interface -lcdda_paranoia
-lcdio_cdda -lcdio_paranoia
# this is where the XML-GUI resource file goes
shellrcdir = $(kde_datadir)/kaffeine

@ -120,7 +120,7 @@ KiloConfig::~KiloConfig()
{
}
void paranoiaCallback( long, int )
void paranoiaCallback( long int, paranoia_cb_mode_t )
{
}
@ -396,7 +396,7 @@ void Paranoia::run()
curpos = currentSector;
endpos = endOfTrack;
if ( normalize ) {
len = CD_FRAMESIZE_RAW;
len = CDIO_CD_FRAMESIZE_RAW;
fn.open( IO_ReadWrite | IO_Truncate );
do {
buf = paranoia_read_limited( p, paranoiaCallback, 3 );
@ -419,7 +419,7 @@ void Paranoia::run()
while ( curpos<endpos && len!=0 );
factor = 32767.0/max;
buf = new signed short[CD_FRAMESIZE_RAW];
buf = new signed short[CDIO_CD_FRAMESIZE_RAW];
fn.at( 0 );
f.open( IO_ReadWrite | IO_Truncate );
currentEncoder->start( encodingList[i].remove(0,3), encodingList[0], encodingList[1], encodingList[i].left(2) );
@ -428,7 +428,7 @@ void Paranoia::run()
f.writeBlock( encoded, len );
do {
len = fn.readBlock( (char*)buf, CD_FRAMESIZE_RAW );
len = fn.readBlock( (char*)buf, CDIO_CD_FRAMESIZE_RAW );
if ( len>0 ) {
if ( max<32760 )
for ( n=0; n<len/2; ++n )
@ -455,7 +455,7 @@ void Paranoia::run()
encoded = currentEncoder->getHeader( len );
if ( encoded )
f.writeBlock( encoded, len );
len = CD_FRAMESIZE_RAW;
len = CDIO_CD_FRAMESIZE_RAW;
do {
buf = paranoia_read_limited( p, paranoiaCallback, 3 );
if ( Q_BYTE_ORDER == Q_BIG_ENDIAN ) {
@ -514,7 +514,7 @@ QString Paranoia::trackSize( int t )
QString s, c;
long total;
total = CD_FRAMESIZE_RAW * (cdda_track_lastsector( d, t+1 )-cdda_track_firstsector( d, t+1 ) );
total = CDIO_CD_FRAMESIZE_RAW * (cdda_track_lastsector( d, t+1 )-cdda_track_firstsector( d, t+1 ) );
if ( total>(1048576 ) ) s = c.setNum(total/1048576.0, 'f', 2)+" "+i18n("MB");
else if ( total>1024 ) s = c.setNum(total/1024.0, 'f', 2)+" "+i18n("KB");
else s = c.setNum(total*1.0, 'f', 2)+" "+i18n("Bytes");
@ -532,8 +532,8 @@ QString Paranoia::trackTime( int t )
long total, time;
int m, s;
if ( t<0 ) total = CD_FRAMESIZE_RAW * (cdda_disc_lastsector( d )-cdda_disc_firstsector( d ) );
else total = CD_FRAMESIZE_RAW * (cdda_track_lastsector( d, t+1 )-cdda_track_firstsector( d, t+1 ) );
if ( t<0 ) total = CDIO_CD_FRAMESIZE_RAW * (cdda_disc_lastsector( d )-cdda_disc_firstsector( d ) );
else total = CDIO_CD_FRAMESIZE_RAW * (cdda_track_lastsector( d, t+1 )-cdda_track_firstsector( d, t+1 ) );
time = (8 * total) / (44100 * 2 * 16);
m = time/60;
s = time%60;

@ -32,8 +32,8 @@
extern "C"
{
#include <cdda_interface.h>
#include <cdda_paranoia.h>
#include <cdio/cdda.h>
#include <cdio/paranoia.h>
}
class KiloConfig : public ParanoiaSettings
@ -91,8 +91,8 @@ private:
bool setPath( QString &path, const QString &artist, const QString &album );
long nTracks;
cdrom_drive *d;
cdrom_paranoia *p;
cdrom_drive_t *d;
cdrom_paranoia_t *p;
long currentSector, endOfTrack;
bool isRunning;
QStringList encodingList;

@ -10,7 +10,7 @@ noinst_HEADERS = koggenc.h
libkaffeineoggvorbis_la_SOURCES = koggenc.cpp oggconfig.ui
libkaffeineoggvorbis_la_LIBADD = ../libkaffeineaudioencoder.la $(LIB_OGGVORBIS)
libkaffeineoggvorbis_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) $(LIB_QT) -lDCOP $(KDE_PLUGIN) $(LIB_KPARTS) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) -avoid-version -no-undefined
libkaffeineoggvorbis_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -avoid-version -no-undefined
# this is where the desktop file will go
partdesktopdir = $(kde_servicesdir)

@ -30,6 +30,8 @@ libkaffeinedvb_la_SOURCES = audioeditor.cpp \
dvbsection.h \
dvbsi.cpp \
dvbsi.h \
camdialog.ui \
cammenudialog.ui \
dvbstream.cpp \
dvbstream.h \
gdvb.h \

@ -0,0 +1,149 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>CamDialog</class>
<widget class="QDialog">
<property name="name">
<cstring>CamDialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>330</width>
<height>198</height>
</rect>
</property>
<property name="caption">
<string>CAM settings</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget" row="0" column="0">
<property name="name">
<cstring>layout5</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout5</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLabel">
<property name="name">
<cstring>textLabel9</cstring>
</property>
<property name="text">
<string>Maximum Concurrent Services:</string>
</property>
</widget>
<widget class="QSpinBox">
<property name="name">
<cstring>maxServiceSpin</cstring>
</property>
<property name="minValue">
<number>1</number>
</property>
</widget>
</hbox>
</widget>
<widget class="QGroupBox">
<property name="name">
<cstring>groupBox1</cstring>
</property>
<property name="title">
<string></string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLabel" row="0" column="0">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>Application Type:</string>
</property>
</widget>
<widget class="QLabel" row="2" column="0">
<property name="name">
<cstring>textLabel3</cstring>
</property>
<property name="text">
<string>Manufacturer Code:</string>
</property>
</widget>
<widget class="QLabel" row="3" column="0">
<property name="name">
<cstring>textLabel4</cstring>
</property>
<property name="text">
<string>Menu String:</string>
</property>
</widget>
<widget class="QLabel" row="2" column="1">
<property name="name">
<cstring>manuCodeLab</cstring>
</property>
<property name="text">
<string>_</string>
</property>
</widget>
<widget class="QLabel" row="1" column="1">
<property name="name">
<cstring>appManuLab</cstring>
</property>
<property name="text">
<string>_</string>
</property>
</widget>
<widget class="QLabel" row="1" column="0">
<property name="name">
<cstring>textLabel2</cstring>
</property>
<property name="text">
<string>Application Manufacturer:</string>
</property>
</widget>
<widget class="QLabel" row="3" column="1">
<property name="name">
<cstring>menuStringLab</cstring>
</property>
<property name="text">
<string>_</string>
</property>
</widget>
<widget class="QLabel" row="0" column="1">
<property name="name">
<cstring>appTypeLab</cstring>
</property>
<property name="text">
<string>_</string>
</property>
</widget>
</grid>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>camMenuBtn</cstring>
</property>
<property name="text">
<string>CAM Menu</string>
</property>
</widget>
</vbox>
</widget>
</grid>
</widget>
<tabstops>
<tabstop>maxServiceSpin</tabstop>
</tabstops>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,67 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>CamMenuDialog</class>
<widget class="QDialog">
<property name="name">
<cstring>CamMenuDialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>317</width>
<height>345</height>
</rect>
</property>
<property name="caption">
<string>CAM Menu</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget" row="0" column="0">
<property name="name">
<cstring>layout7</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QTextBrowser">
<property name="name">
<cstring>menuText</cstring>
</property>
</widget>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout6</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>Your choice (enter to validate):</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>inputLine</cstring>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
</grid>
</widget>
<tabstops>
<tabstop>inputLine</tabstop>
<tabstop>menuText</tabstop>
</tabstops>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -115,6 +115,8 @@ Transponder::Transponder()
coderateH=FEC_AUTO;
bandwidth=BANDWIDTH_AUTO;
snr = 0;
rolloff = ROLLOFF_AUTO;
S2 = 0;
}
Transponder::Transponder( const Transponder &trans )
@ -134,6 +136,8 @@ Transponder::Transponder( const Transponder &trans )
coderateL=trans.coderateL;
coderateH=trans.coderateH;
bandwidth=trans.bandwidth;
rolloff = trans.rolloff;
S2 = trans.S2;
}
bool Transponder::sameAs( Transponder *trans )

@ -101,6 +101,8 @@ public:
fe_code_rate_t coderateH;
fe_bandwidth_t bandwidth;
int snr;
fe_rolloff_t rolloff;
char S2;
};
class ChannelDesc

@ -143,6 +143,9 @@ void ChannelEditor::accept()
else channel->tp.pol = 'h';
channel->tp.coderateH = (fe_code_rate_t)(FEC_NONE+coderateHComb->currentItem());
channel->tp.inversion = (fe_spectral_inversion_t)(INVERSION_OFF+inversionComb->currentItem());
channel->tp.modulation = (fe_modulation_t)(QPSK+modulationComb->currentItem());
channel->tp.S2 = stypeComb->currentItem();
channel->tp.rolloff = (fe_rolloff_t)(ROLLOFF_35+rolloffComb->currentItem() );
}
else if ( channel->tp.type==FE_QAM ) {
channel->tp.freq = freqSpin->value();
@ -165,13 +168,7 @@ void ChannelEditor::accept()
else {
channel->tp.freq = freqSpin->value();
channel->tp.inversion = (fe_spectral_inversion_t)(INVERSION_OFF+inversionComb->currentItem());
switch (modulationComb->currentItem()) {
case 0: channel->tp.modulation = QAM_64; break;
case 1: channel->tp.modulation = QAM_256; break;
case 2: channel->tp.modulation = VSB_8; break;
case 3: channel->tp.modulation = VSB_16; break;
default: channel->tp.modulation = QAM_AUTO; break;
}
channel->tp.modulation = (fe_modulation_t)(QPSK+modulationComb->currentItem());
}
done( Accepted );
@ -187,10 +184,15 @@ void ChannelEditor::initS()
inversionComb->setCurrentItem( INVERSION_OFF+channel->tp.inversion );
coderateHComb->insertStringList( coderateList() );
coderateHComb->setCurrentItem( FEC_NONE+channel->tp.coderateH );
modulationComb->insertStringList( modulationList() );
modulationComb->setCurrentItem( QPSK+channel->tp.modulation );
stypeComb->insertStringList( stypeList() );
stypeComb->setCurrentItem( channel->tp.S2 );
rolloffComb->insertStringList( rolloffList() );
rolloffComb->setCurrentItem( ROLLOFF_35+channel->tp.rolloff );
transmissionComb->setEnabled( false );
coderateLComb->setEnabled( false );
bandwidthComb->setEnabled( false );
modulationComb->setEnabled( false );
hierarchyComb->setEnabled( false );
guardComb->setEnabled( false );
}
@ -211,6 +213,8 @@ void ChannelEditor::initC()
bandwidthComb->setEnabled( false );
hierarchyComb->setEnabled( false );
guardComb->setEnabled( false );
stypeComb->setEnabled( false );
rolloffComb->setEnabled( false );
}
void ChannelEditor::initT()
@ -234,6 +238,8 @@ void ChannelEditor::initT()
guardComb->setCurrentItem( GUARD_INTERVAL_1_32+channel->tp.guard );
srSpin->setEnabled( false );
polGroup->setEnabled( false );
stypeComb->setEnabled( false );
rolloffComb->setEnabled( false );
}
void ChannelEditor::initA()
@ -241,14 +247,8 @@ void ChannelEditor::initA()
freqSpin->setValue( channel->tp.freq );
inversionComb->insertStringList( inversionList() );
inversionComb->setCurrentItem( INVERSION_OFF+channel->tp.inversion );
modulationComb->insertStringList( modulationListAtsc() );
switch (channel->tp.modulation) {
case QAM_64: modulationComb->setCurrentItem(0); break;
case QAM_256: modulationComb->setCurrentItem(1); break;
case VSB_8: modulationComb->setCurrentItem(2); break;
case VSB_16: modulationComb->setCurrentItem(3); break;
default: modulationComb->setCurrentItem(4); break;
}
modulationComb->insertStringList( modulationList() );
modulationComb->setCurrentItem( QPSK+channel->tp.modulation );
srSpin->setEnabled( false );
polGroup->setEnabled( false );
transmissionComb->setEnabled( false );
@ -257,6 +257,8 @@ void ChannelEditor::initA()
bandwidthComb->setEnabled( false );
hierarchyComb->setEnabled( false );
guardComb->setEnabled( false );
stypeComb->setEnabled( false );
rolloffComb->setEnabled( false );
}
QStringList ChannelEditor::inversionList()
@ -271,7 +273,7 @@ QStringList ChannelEditor::coderateList()
{
QStringList list;
list<<"NONE"<<"1/2"<<"2/3"<<"3/4"<<"4/5"<<"5/6"<<"6/7"<<"7/8"<<"8/9"<<"AUTO";
list<<"NONE"<<"1/2"<<"2/3"<<"3/4"<<"4/5"<<"5/6"<<"6/7"<<"7/8"<<"8/9"<<"AUTO"<<"3/5"<<"9/10";
return list;
}
@ -279,15 +281,7 @@ QStringList ChannelEditor::modulationList()
{
QStringList list;
list<<"QPSK"<<"QAM 16"<<"QAM 32"<<"QAM 64"<<"QAM 128"<<"QAM 256"<<"AUTO";
return list;
}
QStringList ChannelEditor::modulationListAtsc()
{
QStringList list;
list<<"QAM 64"<<"QAM 256"<<"VSB 8"<<"VSB 16"<<"AUTO";
list<<"QPSK"<<"QAM 16"<<"QAM 32"<<"QAM 64"<<"QAM 128"<<"QAM 256"<<"AUTO"<<"VSB-8"<<"VSB-16"<<"8PSK"<<"16APSK"<<"DQPSK";
return list;
}
@ -323,6 +317,22 @@ QStringList ChannelEditor::guardList()
return list;
}
QStringList ChannelEditor::stypeList()
{
QStringList list;
list<<"DVB-S"<<"DVB-S2";
return list;
}
QStringList ChannelEditor::rolloffList()
{
QStringList list;
list<<"35"<<"20"<<"25"<<"AUTO";
return list;
}
ChannelEditor::~ChannelEditor()
{
}

@ -53,11 +53,12 @@ private:
QStringList inversionList();
QStringList coderateList();
QStringList modulationList();
QStringList modulationListAtsc();
QStringList transmissionList();
QStringList bandwidthList();
QStringList hierarchyList();
QStringList guardList();
QStringList stypeList();
QStringList rolloffList();
ChannelDesc *channel;
QPtrList<ChannelDesc> *chandesc;

@ -9,7 +9,7 @@
<x>0</x>
<y>0</y>
<width>477</width>
<height>533</height>
<height>541</height>
</rect>
</property>
<property name="caption">
@ -19,7 +19,7 @@
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="Line" row="1" column="0">
<widget class="Line" row="0" column="1">
<property name="name">
<cstring>line2</cstring>
</property>
@ -35,7 +35,7 @@
</widget>
<widget class="QLayoutWidget" row="0" column="0">
<property name="name">
<cstring>layout9</cstring>
<cstring>layout7</cstring>
</property>
<vbox>
<property name="name">
@ -432,22 +432,6 @@
<cstring>transmissionComb</cstring>
</property>
</widget>
<widget class="QLabel" row="3" column="0">
<property name="name">
<cstring>textLabel11</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>5</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Bandwidth:</string>
</property>
</widget>
<widget class="QLabel" row="2" column="0">
<property name="name">
<cstring>textLabel10</cstring>
@ -480,11 +464,6 @@
<string>Transmission:</string>
</property>
</widget>
<widget class="QComboBox" row="3" column="1">
<property name="name">
<cstring>bandwidthComb</cstring>
</property>
</widget>
<widget class="QComboBox" row="2" column="1">
<property name="name">
<cstring>coderateHComb</cstring>
@ -511,11 +490,6 @@
<string>FEC low:</string>
</property>
</widget>
<widget class="QComboBox" row="3" column="3">
<property name="name">
<cstring>guardComb</cstring>
</property>
</widget>
<widget class="QLabel" row="3" column="2">
<property name="name">
<cstring>textLabel7</cstring>
@ -595,6 +569,58 @@
<string>Inversion:</string>
</property>
</widget>
<widget class="QLabel" row="3" column="0">
<property name="name">
<cstring>textLabel11</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>5</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Bandwidth:</string>
</property>
</widget>
<widget class="QComboBox" row="3" column="1">
<property name="name">
<cstring>bandwidthComb</cstring>
</property>
</widget>
<widget class="QLabel" row="4" column="0">
<property name="name">
<cstring>textLabel1_3</cstring>
</property>
<property name="text">
<string>Type:</string>
</property>
</widget>
<widget class="QComboBox" row="4" column="1">
<property name="name">
<cstring>stypeComb</cstring>
</property>
</widget>
<widget class="QComboBox" row="4" column="3">
<property name="name">
<cstring>rolloffComb</cstring>
</property>
</widget>
<widget class="QLabel" row="4" column="2">
<property name="name">
<cstring>textLabel2_4</cstring>
</property>
<property name="text">
<string>Roll off:</string>
</property>
</widget>
<widget class="QComboBox" row="3" column="3">
<property name="name">
<cstring>guardComb</cstring>
</property>
</widget>
</grid>
</widget>
<spacer>
@ -610,7 +636,7 @@
<property name="sizeHint">
<size>
<width>20</width>
<height>98</height>
<height>166</height>
</size>
</property>
</spacer>

File diff suppressed because it is too large Load Diff

@ -1,6 +1,7 @@
/*
* dvbcam.h
*
* Copyright (C) 2008 Christophe Thommeret <hftom@free.fr>
* Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@ -21,32 +22,182 @@
#ifndef DVBCAM_H
#define DVBCAM_H
class DvbCamCamThread;
class DvbCamPmtThread;
#include <libdvbapi/dvbca.h>
#include <libdvbapi/dvbdemux.h>
#include <libdvben50221/en50221_app_ai.h>
#include <libdvben50221/en50221_app_ca.h>
#include <libdvben50221/en50221_app_mmi.h>
#include <libdvben50221/en50221_app_rm.h>
#include <libdvben50221/en50221_app_tags.h>
#include <libdvben50221/en50221_session.h>
#include <libdvben50221/en50221_stdcam.h>
#include <libucsi/mpeg/section.h>
class DvbCam
#include <qthread.h>
#include <qmutex.h>
#include <qptrlist.h>
#include "channeldesc.h"
#include "camdialog.h"
#include "cammenudialog.h"
#define MMI_STATE_CLOSED 0
#define MMI_STATE_OPEN 1
#define MMI_STATE_ENQ 2
#define MMI_STATE_MENU 3
#define MMI_NO_MENU 0
#define MMI_MENU 1
class CamService : protected QThread
{
public:
DvbCam(int adapter, int ca_device, int demux_device, int ci_type);
~DvbCam();
enum PmtState{ NotReady=0, Ready, Added, Remove, Destroy };
CamService( int adapter, int demux_device, ChannelDesc *chan, int maxService );
~CamService();
void setState( PmtState st );
int getState();
const ChannelDesc& getChannel() { return channel; }
void restart();
void restart(int service_id);
unsigned char caPmt[4096];
int caPmtSize;
protected:
void run();
private:
int createSectionFilter( uint16_t pid, uint8_t table_id );
int processPat( int demux_fd );
int processPmt( int demux_fd );
bool setCaPmt( int list_management, int cmd_id );
void stop();
bool running() { return isRunning; }
int serviceId() { return sid; }
int Adapter;
int DemuxDevice;
ChannelDesc channel;
unsigned char pmtBuffer[4096];
struct mpeg_pmt_section *parsedPmt;
PmtState state;
bool isRunning;
QMutex mutex;
int CamMaxService;
};
class DvbCam;
class StandardCam
{
public:
StandardCam( en50221_stdcam *sc, DvbCam *dc ) {
stdcam=sc;
dvbcam=dc;
mmi_state=MMI_STATE_CLOSED;
menuType=MMI_NO_MENU;
}
en50221_stdcam *stdcam;
DvbCam *dvbcam;
int mmi_state;
int mmi_enq_blind;
int mmi_enq_length;
int menuType;
QStringList menuList;
QMutex mutex;
};
class MCamMenuDialog : public CamMenuDialog
{
Q_OBJECT
public:
MCamMenuDialog( StandardCam *sc );
private:
StandardCam *stdcam;
QTimer readTimer;
private slots:
void setMenu();
void validateClicked();
signals:
void enteredResponse( QString );
};
class DvbCam : public QObject, public QThread
{
Q_OBJECT
public:
DvbCam(int adapter, int ca_device, int demux_device, int ci_type, int maxService);
~DvbCam();
void startService( ChannelDesc *chan );
void stopService( ChannelDesc *chan );
bool canPlay( ChannelDesc *chan );
static int probe( int adapter, int ca_device );
void setAppType( QString s ) { appType=s; }
void setAppManu( QString s ) { appManu=s; }
void setManuCode( QString s ) { manuCode=s; }
void setMenuString( QString s ) { menuString=s; }
QString getAppType() { return appType; }
QString getAppManu() { return appManu; }
QString getManuCode() { return manuCode; }
QString getMenuString() { return menuString; }
int getCamMaxService() { return CamMaxService; }
int showCamDialog();
protected:
void run();
void timerEvent( QTimerEvent *e );
private slots:
void mmiResponse( QString s );
void showMMI();
void closeMMI();
void enterMenu();
private:
bool init();
bool sendPmt( unsigned char *pmt_buffer, int size );
void resendPmts();
static int infoCallback(void *arg, uint8_t slot_id, uint16_t session_number, uint32_t ca_id_count, uint16_t *ca_ids);
static int aiCallback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t application_type,
uint16_t application_manufacturer, uint16_t manufacturer_code, uint8_t menu_string_length, uint8_t *menu_string);
static int mmi_close_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t cmd_id, uint8_t delay);
static int mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t cmd_id, uint8_t mmi_mode);
static int mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t blind_answer, uint8_t expected_answer_length,
uint8_t *text, uint32_t text_size);
static int mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t session_number, struct en50221_app_mmi_text *title,
struct en50221_app_mmi_text *sub_title, struct en50221_app_mmi_text *bottom, uint32_t item_count,
struct en50221_app_mmi_text *items, uint32_t item_raw_length, uint8_t *items_raw);
int Adapter;
int CaDevice;
int DemuxDevice;
bool isRunning;
int sid;
int ciType;
int CamMaxService;
bool isRunning;
QPtrList<CamService> sidList;
QMutex sidMutex;
QString appType, appManu, manuCode, menuString;
StandardCam *stdcam;
en50221_session_layer *SessionLayer;
en50221_transport_layer *TransportLayer;
DvbCamCamThread *CamThread;
DvbCamPmtThread *PmtThread;
MCamMenuDialog *menuDialog;
};
#endif /* DVBCAM_H */

@ -38,6 +38,7 @@
#include "dvbconfig.h"
#include "kaffeinedvbplugin.h"
#include "dvbpanel.h"
@ -72,6 +73,21 @@ void MPushButton::isClicked()
MCAMButton::MCAMButton( QWidget *parent, int devNum ) : QPushButton( i18n("CAM"), parent )
{
deviceNumber = devNum;
connect( this, SIGNAL(clicked()), this, SLOT(isClicked()) );
}
void MCAMButton::isClicked()
{
emit clicked( deviceNumber );
}
MComboBox::MComboBox( QWidget *parent, int devNum, int lnbNum ) : QComboBox( parent )
{
deviceNumber = devNum;
@ -109,6 +125,12 @@ Device::Device( int anum, int tnum, fe_type_t t, const QString &n, bool as )
source = "";
canAutoscan= as;
tuningTimeout = 1500;
hasCAM = false;
camMaxService = 1;
secMini = 0;
secTwice = 0;
priority = 10;
doS2 = 0;
}
@ -134,6 +156,7 @@ DVBconfig::DVBconfig( const QString &dvbConf )
sizeFile = 0;
categories.setAutoDelete( true );
devList.setAutoDelete( true );
readFirst();
startup();
readConfig();
}
@ -187,6 +210,7 @@ void DVBconfig::startup()
int i=0, j=0, res, fdFrontend=0;
struct dvb_frontend_info info;
bool as;
QTime t1;
QStringList list, flist;
QString s, t;
@ -200,6 +224,11 @@ void DVBconfig::startup()
for ( j=0; j<(int)flist.count(); j++ ) {
s = list[i];
t = flist[j];
if ( devList.count()==MAX_DEVICES )
break;
if ( !probeMfe && t!="frontend0" )
continue;
t1 = QTime::currentTime();
fdFrontend = open( QString("/dev/dvb/%1/%2").arg( s ).arg( t ).ascii(), O_RDWR);
if ( fdFrontend>0 ) {
if ( !(res = ioctl( fdFrontend, FE_GET_INFO, &info ) < 0) ) {
@ -212,13 +241,14 @@ void DVBconfig::startup()
as = true;
else
as = false;
fprintf(stderr,"/dev/dvb/%s/%s : opened ( %s )\n", s.ascii(), t.ascii(), info.name );
fprintf(stderr,"/dev/dvb/%s/%s : opened ( %s ) (%dms)\n", s.ascii(), t.ascii(), info.name, t1.msecsTo(QTime::currentTime()) );
devList.append( new Device( s.replace("adapter","").toInt(), t.replace("frontend","").toInt(), info.type, info.name, as ) );
}
close( fdFrontend );
}
else
perror( QString("/dev/dvb/%1/%2").arg( s ).arg( t ).ascii() );
else {
perror( QString("/dev/dvb/%1/%2 %3/%4").arg( s ).arg( t ).arg( errno ).arg( -EBUSY ).ascii() );
}
}
}
@ -292,9 +322,9 @@ bool DVBconfig::localData()
bool DVBconfig::haveData()
{
if ( !QDir( dvbConfigDir+"dvb-s" ).exists() || !QDir( dvbConfigDir+"dvb-c" ).exists() || !QDir( dvbConfigDir+"dvb-t" ).exists() ) {
if ( !QDir( dvbConfigDir+"dvb-s" ).exists() || !QDir( dvbConfigDir+"dvb-c" ).exists() || !QDir( dvbConfigDir+"dvb-t" ).exists() || !QDir( dvbConfigDir+"atsc" ).exists()) {
loadDvbData(0);
if ( !QDir( dvbConfigDir+"dvb-s" ).exists() || !QDir( dvbConfigDir+"dvb-c" ).exists() || !QDir( dvbConfigDir+"dvb-t" ).exists() ) {
if ( !QDir( dvbConfigDir+"dvb-s" ).exists() || !QDir( dvbConfigDir+"dvb-c" ).exists() || !QDir( dvbConfigDir+"dvb-t" ).exists() || !QDir( dvbConfigDir+"atsc" ).exists() ) {
if ( !localData() )
return false;
}
@ -313,6 +343,7 @@ QStringList DVBconfig::getSourcesList( fe_type_t type )
case FE_QPSK : s = "dvb-s"; break;
case FE_QAM : s = "dvb-c"; break;
case FE_OFDM : s = "dvb-t"; break;
case FE_ATSC : s = "atsc"; break;
default : return list;
}
list = QDir( dvbConfigDir+s ).entryList( QDir::Files, QDir::Name );
@ -383,6 +414,14 @@ void DVBconfig::saveDvbChanOrder( int s, int col )
void DVBconfig::readFirst()
{
config->setGroup( "DVB Options" );
probeMfe = config->readNumEntry( "ProbeMFE", 1 );
}
void DVBconfig::readConfig()
{
QSize size;
@ -413,6 +452,8 @@ void DVBconfig::readConfig()
for ( i=0; i<(int)devList.count(); i++ ) {
devList.at(i)->source = config->readEntry( QString("DVB%1").arg(i), "" );
devList.at(i)->tuningTimeout = config->readNumEntry( QString("DVB%1_TIMEOUT").arg(i), 1500 );
devList.at(i)->camMaxService = config->readNumEntry( QString("DVB%1_CAM_MAX").arg(i), 1 );
devList.at(i)->priority = config->readNumEntry( QString("DVB%1_PRIORITY").arg(i), 10 );
if ( devList.at(i)->type!=FE_QPSK )
continue;
devList.at(i)->numLnb = config->readNumEntry( QString("DVB%1_NLNB").arg(i), 1 );
@ -426,6 +467,9 @@ void DVBconfig::readConfig()
devList.at(i)->lnb[j].speed13v = config->readDoubleNumEntry( QString("DVB%1_LNB%2_speed13v").arg(i).arg(j), 2.5 );
devList.at(i)->lnb[j].speed18v = config->readDoubleNumEntry( QString("DVB%1_LNB%2_speed18v").arg(i).arg(j), 1.5 );
}
devList.at(i)->secMini = config->readNumEntry( QString("DVB%1_SEC_MINI").arg(i), 0 );
devList.at(i)->secTwice = config->readNumEntry( QString("DVB%1_SEC_TWICE").arg(i), 0 );
devList.at(i)->doS2 = config->readNumEntry( QString("DVB%1_DOS2").arg(i), 0 );
}
j = config->readNumEntry( "NumCategories", 0 );
for ( i=0; i<j; i++ )
@ -442,6 +486,9 @@ void DVBconfig::readConfig()
devList.at(i)->usalsLatitude = usalsLatitude;
devList.at(i)->usalsLongitude = usalsLongitude;
}
ringBufSize = config->readNumEntry( "RingBufSize", 2 );
if ( ringBufSize<2 )
ringBufSize = 2;
}
@ -463,9 +510,12 @@ void DVBconfig::saveConfig()
config->writeEntry( "BroadcastAddress", broadcastAddress );
config->writeEntry( "BroadcastPort", broadcastPort );
config->writeEntry( "SenderPort", senderPort );
config->writeEntry( "ProbeMFE", probeMfe );
for ( i=0; i<(int)devList.count(); i++ ) {
config->writeEntry( QString("DVB%1").arg(i), devList.at(i)->source );
config->writeEntry( QString("DVB%1_TIMEOUT").arg(i), devList.at(i)->tuningTimeout );
config->writeEntry( QString("DVB%1_PRIORITY").arg(i), devList.at(i)->priority );
config->writeEntry( QString("DVB%1_CAM_MAX").arg(i), devList.at(i)->camMaxService );
if ( devList.at(i)->type!=FE_QPSK )
continue;
config->writeEntry( QString("DVB%1_NLNB").arg(i), devList.at(i)->numLnb );
@ -479,6 +529,9 @@ void DVBconfig::saveConfig()
config->writeEntry( QString("DVB%1_LNB%2_speed13v").arg(i).arg(j), devList.at(i)->lnb[j].speed13v );
config->writeEntry( QString("DVB%1_LNB%2_speed18v").arg(i).arg(j), devList.at(i)->lnb[j].speed18v );
}
config->writeEntry( QString("DVB%1_SEC_MINI").arg(i), devList.at(i)->secMini );
config->writeEntry( QString("DVB%1_SEC_TWICE").arg(i), devList.at(i)->secTwice );
config->writeEntry( QString("DVB%1_DOS2").arg(i), devList.at(i)->doS2 );
}
config->writeEntry( "NumCategories", categories.count() );
for ( i=0; i<(int)categories.count(); i++ ) {
@ -494,6 +547,7 @@ void DVBconfig::saveConfig()
config->writeEntry( "UsalsLatitude", usalsLatitude );
config->writeEntry( "UsalsLongitude", usalsLongitude );
config->writeEntry( "SizeFile", sizeFile );
config->writeEntry( "RingBufSize", ringBufSize );
config->sync();
}
@ -511,7 +565,7 @@ bool DVBconfig::firstRun()
DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlugin *p ) :
DvbConfigDialog::DvbConfigDialog( DvbPanel *pan, DVBconfig *dc, QWidget *parent, KaffeineDvbPlugin *p ) :
KDialogBase ( IconList, i18n("DVB Settings"), Ok|Cancel, Ok, parent, "dvbConfigDialog", true, true )
{
QLabel *lab;
@ -529,7 +583,7 @@ DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlu
QSpinBox *spin;
KPushButton *usals;
QWidget *swidg;
QStringList rotorList; rotorList<<i18n("No rotor")<<i18n("USALS rotor")<<i18n("Positions rotor");
QStringList rotorList; rotorList<<i18n("No rotor")<<i18n("USALS rotor")<<i18n("Positions rotor")<<i18n("External positionner");
dvbConfig = dc;
timeoutSpin.setAutoDelete( true );
@ -558,7 +612,22 @@ DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlu
case FE_ATSC : dvbType->setText( i18n("Atsc") ); break;
default : dvbType->setText( i18n("Unknown") );
}
grid->addMultiCellWidget( dvbType, gridLine, gridLine, 1, 3 );
if ( dvbConfig->devList.at(i)->hasCAM ) {
grid->addWidget( dvbType, gridLine, 1 );
MCAMButton *camb = new MCAMButton( gb, i );
connect( camb, SIGNAL(clicked(int)), pan, SLOT(camClicked(int)) );
grid->addWidget( camb, gridLine, 2 );
}
else
grid->addMultiCellWidget( dvbType, gridLine, gridLine, 1, 3 );
++gridLine;
lab = new QLabel( i18n("Tuner priority (0=Don't use):"), gb );
grid->addWidget( lab, gridLine, 0 );
spin = new QSpinBox( 0, 99, 1, gb );
spin->setValue( dvbConfig->devList.at(i)->priority );
priority.append( spin );
grid->addWidget( spin, gridLine, 1 );
++gridLine;
lab = new QLabel( i18n("Tuner timeout :"), gb );
@ -572,6 +641,11 @@ DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlu
++gridLine;
if ( dvbConfig->devList.at(i)->type==FE_QPSK ) {
doS2[i] = new QCheckBox( i18n("S2 capable device"), gb );
doS2[i]->setChecked( dvbConfig->devList.at(i)->doS2 );
grid->addWidget( doS2[i], gridLine, 0 );
++gridLine;
lab = new QLabel( i18n("Number of LNBs:"), gb );
grid->addWidget( lab, gridLine, 0 );
satNumber[i] = new MSpinBox( gb, i );
@ -582,6 +656,16 @@ DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlu
connect( usals, SIGNAL(clicked()), this, SLOT(setUsals()));
grid->addWidget( usals, gridLine, 2 );
++gridLine;
secMini[i] = new QCheckBox( i18n("Mini DiSEqC (A-B)."), gb );
secMini[i]->setChecked( dvbConfig->devList.at(i)->secMini );
secMini[i]->setEnabled( false );
grid->addWidget( secMini[i], gridLine, 1 );
secTwice[i] = new QCheckBox( i18n("Send DiSEqC commands twice."), gb );
secTwice[i]->setChecked( dvbConfig->devList.at(i)->secTwice );
grid->addWidget( secTwice[i], gridLine, 0 );
++gridLine;
lnb0[i] = new MPushButton( gb, i, 0 );
@ -853,9 +937,19 @@ DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlu
vb = new QVBoxLayout( page, 6, 6 );
gb = new QGroupBox( "", page );
grid = new QGridLayout( gb, 1, 1, 20, 6 );
probeMfe = new QCheckBox( i18n("Probe Multiple-Frontends (Restart required)."), gb );
probeMfe->setChecked( dvbConfig->probeMfe );
grid->addWidget( probeMfe, 0, 0 );
lab = new QLabel( i18n("LiveShow ringbuffer size (MB) :"), gb );
grid->addWidget( lab, 1, 0 );
ringBufSize = new QSpinBox( 2, 99, 1, gb );
ringBufSize->setValue( dvbConfig->ringBufSize );
grid->addWidget( ringBufSize, 1, 1 );
lab = new QLabel( i18n("Default charset (restart needed):"), gb );
grid->addWidget( lab, 0, 0 );
grid->addWidget( lab, 2, 0 );
charsetComb = new QComboBox( gb );
charsetComb->insertItem( "ISO8859-1" );
charsetComb->insertItem( "ISO6937" );
@ -863,19 +957,19 @@ DvbConfigDialog::DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlu
charsetComb->setCurrentItem( 0 );
else if ( dvbConfig->defaultCharset=="ISO6937" )
charsetComb->setCurrentItem( 1 );
grid->addWidget( charsetComb, 0, 1 );
grid->addWidget( charsetComb, 2, 1 );
lab = new QLabel( i18n("Update scan data:"), gb );
grid->addWidget( lab, 1, 0 );
grid->addWidget( lab, 3, 0 );
updateBtn = new KPushButton( gb );
updateBtn->setGuiItem( KGuiItem(i18n("Download"), icon->loadIconSet("khtml_kget", KIcon::Small) ) );
grid->addWidget( updateBtn, 1, 1 );
grid->addWidget( updateBtn, 3, 1 );
lab = new QLabel( i18n("Dump epg's events to \n~/kaffeine_dvb_events.tx:"), gb );
grid->addWidget( lab, 2, 0 );
grid->addWidget( lab, 4, 0 );
dumpBtn = new KPushButton( gb );
dumpBtn->setGuiItem( KGuiItem(i18n("Dump"), icon->loadIconSet("filesave", KIcon::Small) ) );
grid->addWidget( dumpBtn, 2, 1 );
grid->addWidget( dumpBtn, 4, 1 );
vb->addWidget( gb );
vb->addItem( new QSpacerItem( 20, 20, QSizePolicy::Ignored, QSizePolicy::Ignored ) );
@ -1039,6 +1133,8 @@ void DvbConfigDialog::satNumberChanged( int value, int devNum )
rotor1[devNum]->setEnabled( value > 1 );
rotor2[devNum]->setEnabled( value > 2 );
rotor3[devNum]->setEnabled( value > 3 );
secMini[devNum]->setEnabled( value==2 );
}
@ -1103,6 +1199,9 @@ void DvbConfigDialog::accept()
switch (dvbConfig->devList.at(i)->type) {
case FE_QPSK: {
dvbConfig->devList.at(i)->numLnb = satNumber[i]->value();
dvbConfig->devList.at(i)->secMini = secMini[i]->isChecked();
dvbConfig->devList.at(i)->secTwice = secTwice[i]->isChecked();
dvbConfig->devList.at(i)->doS2 = doS2[i]->isChecked();
if ( dvbConfig->devList.at(i)->lnb[3].rotorType==0 ) {
dvbConfig->devList.at(i)->lnb[3].source.clear();
dvbConfig->devList.at(i)->lnb[3].source.append(sat3[i]->currentText());
@ -1140,6 +1239,7 @@ void DvbConfigDialog::accept()
}
dvbConfig->devList.at(i)->source = s;
dvbConfig->devList.at(i)->tuningTimeout = timeoutSpin.at(i)->value();
dvbConfig->devList.at(i)->priority = priority.at(i)->value();
}
dvbConfig->recordDir = recordDirLe->text();
@ -1157,6 +1257,8 @@ void DvbConfigDialog::accept()
dvbConfig->broadcastAddress = broadcastLe->text().stripWhiteSpace();
dvbConfig->broadcastPort = bportSpin->value();
dvbConfig->senderPort = sportSpin->value();
dvbConfig->probeMfe = probeMfe->isChecked();
dvbConfig->ringBufSize = ringBufSize->value();
dvbConfig->saveConfig();
done( Accepted );
}
@ -1403,22 +1505,24 @@ RotorConfig::RotorConfig( Device *d, DVBconfig *c, int lnb, QWidget *parent ) :
vb->addWidget( resetBtn );
vb->addItem( new QSpacerItem( 20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed ) );
grid = new QGridLayout( 0, 1, 1 );
lab = new QLabel( i18n("13V rotor speed:"), page );
grid->addWidget( lab, 0, 0 );
speed13 = new QLineEdit( page );
speed13->setText( QString().setNum( dev->lnb[lnbNum].speed13v ) );
grid->addWidget( speed13, 0, 1 );
lab = new QLabel( i18n("sec./ °"), page );
grid->addWidget( lab, 0, 2 );
lab = new QLabel( i18n("18V rotor speed:"), page );
grid->addWidget( lab, 1, 0 );
speed18 = new QLineEdit( page );
speed18->setText( QString().setNum( dev->lnb[lnbNum].speed18v ) );
grid->addWidget( speed18, 1, 1 );
lab = new QLabel( i18n("sec./ °"), page );
grid->addWidget( lab, 1, 2 );
vb->addLayout( grid );
if ( dev->lnb[lnbNum].rotorType!=3 ) {
grid = new QGridLayout( 0, 1, 1 );
lab = new QLabel( i18n("13V rotor speed:"), page );
grid->addWidget( lab, 0, 0 );
speed13 = new QLineEdit( page );
speed13->setText( QString().setNum( dev->lnb[lnbNum].speed13v ) );
grid->addWidget( speed13, 0, 1 );
lab = new QLabel( i18n("sec./ °"), page );
grid->addWidget( lab, 0, 2 );
lab = new QLabel( i18n("18V rotor speed:"), page );
grid->addWidget( lab, 1, 0 );
speed18 = new QLineEdit( page );
speed18->setText( QString().setNum( dev->lnb[lnbNum].speed18v ) );
grid->addWidget( speed18, 1, 1 );
lab = new QLabel( i18n("sec./ °"), page );
grid->addWidget( lab, 1, 2 );
vb->addLayout( grid );
}
vb->addItem( new QSpacerItem( 20, 20, QSizePolicy::Ignored, QSizePolicy::Ignored ) );
@ -1462,8 +1566,14 @@ void RotorConfig::accept()
{
QListViewItem *it;
dev->lnb[lnbNum].speed18v = speed18->text().toDouble();
dev->lnb[lnbNum].speed13v = speed13->text().toDouble();
if ( dev->lnb[lnbNum].rotorType!=3 ) {
dev->lnb[lnbNum].speed18v = speed18->text().toDouble();
dev->lnb[lnbNum].speed13v = speed13->text().toDouble();
}
else {
dev->lnb[lnbNum].speed18v = 0;
dev->lnb[lnbNum].speed13v = 0;
}
dev->lnb[lnbNum].source.clear();
dev->lnb[lnbNum].position.clear();
for ( it=listView->firstChild(); it; it=it->nextSibling() ) {

@ -28,6 +28,7 @@
#include <qtoolbutton.h>
#include <qbuttongroup.h>
#include <qlistview.h>
#include <qcheckbox.h>
#include <kdialogbase.h>
#include <kpushbutton.h>
@ -37,6 +38,8 @@
#include <linux/dvb/frontend.h>
#define MAX_DEVICES 8
using namespace KIO;
class MSpinBox : public QSpinBox
@ -70,6 +73,21 @@ private:
class MCAMButton : public QPushButton
{
Q_OBJECT
public:
MCAMButton( QWidget *parent, int devNum );
private slots:
void isClicked();
signals:
void clicked( int devnum );
private:
int deviceNumber;
};
class MComboBox : public QComboBox
{
Q_OBJECT
@ -116,6 +134,12 @@ public:
bool canAutoscan;
int tuningTimeout;
double usalsLatitude, usalsLongitude;
bool hasCAM;
int camMaxService;
int secMini;
int secTwice;
int priority;
int doS2;
};
@ -138,6 +162,7 @@ public:
DVBconfig( const QString &dvbConf );
~DVBconfig();
void readFirst();
void readConfig();
void saveConfig();
int readDvbChanOrder();
@ -168,6 +193,8 @@ public:
QValueList<int> splitSizes;
QString defaultCharset;
double usalsLatitude, usalsLongitude;
int probeMfe;
int ringBufSize;
private:
@ -183,6 +210,7 @@ private slots:
class KaffeineDvbPlugin;
class DvbPanel;
class DvbConfigDialog : public KDialogBase
{
@ -190,34 +218,39 @@ class DvbConfigDialog : public KDialogBase
public:
DvbConfigDialog( DVBconfig *dc, QWidget *parent, KaffeineDvbPlugin *p );
DvbConfigDialog( DvbPanel *pan, DVBconfig *dc, QWidget *parent, KaffeineDvbPlugin *p );
~DvbConfigDialog();
void setSource( QComboBox *box, QString s );
QLineEdit *recordDirLe, *shiftDirLe, *broadcastLe, *filenameFormatLe;
QSpinBox *beginSpin, *endSpin, *instantDurationSpin, *bportSpin, *sportSpin, *sizeFileSpin;
MSpinBox *satNumber[8];
QComboBox *sat0[8];
QComboBox *sat1[8];
QComboBox *sat2[8];
QComboBox *sat3[8];
MPushButton *src0[8];
MPushButton *src1[8];
MPushButton *src2[8];
MPushButton *src3[8];
MComboBox *rotor0[8];
MComboBox *rotor1[8];
MComboBox *rotor2[8];
MComboBox *rotor3[8];
MPushButton *lnb0[8];
MPushButton *lnb1[8];
MPushButton *lnb2[8];
MPushButton *lnb3[8];
MSpinBox *satNumber[MAX_DEVICES];
QCheckBox *secMini[MAX_DEVICES], *secTwice[MAX_DEVICES];
QCheckBox *doS2[MAX_DEVICES];
QComboBox *sat0[MAX_DEVICES];
QComboBox *sat1[MAX_DEVICES];
QComboBox *sat2[MAX_DEVICES];
QComboBox *sat3[MAX_DEVICES];
MPushButton *src0[MAX_DEVICES];
MPushButton *src1[MAX_DEVICES];
MPushButton *src2[MAX_DEVICES];
MPushButton *src3[MAX_DEVICES];
MComboBox *rotor0[MAX_DEVICES];
MComboBox *rotor1[MAX_DEVICES];
MComboBox *rotor2[MAX_DEVICES];
MComboBox *rotor3[MAX_DEVICES];
MPushButton *lnb0[MAX_DEVICES];
MPushButton *lnb1[MAX_DEVICES];
MPushButton *lnb2[MAX_DEVICES];
MPushButton *lnb3[MAX_DEVICES];
KPushButton *updateBtn, *dumpBtn;
QToolButton *recordDirBtn, *shiftDirBtn, *helpNameBtn;
DVBconfig *dvbConfig;
QComboBox *charsetComb;
QPtrList<QSpinBox> timeoutSpin;
QPtrList<QSpinBox> priority;
QCheckBox *probeMfe;
QSpinBox *ringBufSize;
private slots:

@ -136,19 +136,23 @@ void DVBout::writePmt()
tspmt[0x0a] = 0xc1;
// section # and last section #
tspmt[0x0b] = tspmt[0x0c] = 0x00;
// PCR PID
tspmt[0x0d] = channel.vpid>>8; tspmt[0x0e] = channel.vpid&0xff;
if ( channel.vpid ) {
// PCR PID
tspmt[0x0d] = channel.vpid>>8; tspmt[0x0e] = channel.vpid&0xff;
}
else if ( channel.napid )
tspmt[0x0d] = channel.apid[0].pid>>8; tspmt[0x0e] = channel.apid[0].pid&0xff;
// program_info_length == 0
tspmt[0x0f] = 0xf0; tspmt[0x10] = 0x00;
// Program Map / Video PID
tspmt[0x11] = channel.vType; // video stream type
tspmt[0x12] = channel.vpid>>8; tspmt[0x13] = channel.vpid&0xff;
tspmt[0x14] = 0xf0; tspmt[0x15] = 0x09; // es info length
// useless info
tspmt[0x16] = 0x07; tspmt[0x17] = 0x04; tspmt[0x18] = 0x08; tspmt[0x19] = 0x80;
tspmt[0x1a] = 0x24; tspmt[0x1b] = 0x02; tspmt[0x1c] = 0x11; tspmt[0x1d] = 0x01;
tspmt[0x1e] = 0xfe;
off = 0x1e;
if ( channel.vpid ) {
// Program Map / Video PID
tspmt[0x11] = channel.vType; // video stream type
tspmt[0x12] = channel.vpid>>8; tspmt[0x13] = channel.vpid&0xff;
tspmt[0x14] = 0xf0; tspmt[0x15] = 0x00; // es info length
off = 0x15;
}
else
off = 0x10;
// audio pids
i = 0;
for ( i=0; i<channel.napid && i<MAX_AUDIO; i++ ) {
@ -258,20 +262,19 @@ bool DVBout::doPause( const QString &name ) // called from dvbstream::run()
liveFile.writeBlock( (char*)tspmt, TS_SIZE );
mutex.lock();
haveLive = false;
mutex.unlock();
if ( !wait(100) ) {
if ( !wait(1000) ) {
terminate();
wait();
}
mutex.lock();
haveLive = true;
if ( close( fdPipe )<0 )
perror("close out pipe: ");
else
fprintf(stderr,"out pipe closed\n");
fdPipe = 0;
mutex.unlock();
if ( wDist>0 )
liveFile.writeBlock( (char*)(wBuf+(wRead*TS_SIZE*NTS)), TS_SIZE*NTS*wDist );
timeShifting = true;
mutex.unlock();
//emit shifting( timeShifting );
}
return true;
@ -286,7 +289,7 @@ void DVBout::setPatPmt()
bool DVBout::goLive( const QString &name )
bool DVBout::goLive( const QString &name, int ringBufSize )
{
if ( fdPipe ) return false;
@ -299,7 +302,8 @@ bool DVBout::goLive( const QString &name )
writePmt();
if ( !pids.contains(8192) )
patpmt = wpatpmt = true;
wBuf = new unsigned char[TS_SIZE*NTS*100];
wbufSize = ringBufSize*1024*1024/(TS_SIZE*NTS);
wBuf = new unsigned char[TS_SIZE*NTS*wbufSize];
if ( !wBuf ) fprintf( stderr, "\nNO WBUF !!!\n\n" );
wRead = wWrite = wDist = 0;
start();
@ -326,7 +330,7 @@ void DVBout::stopLive()
emit shifting( timeShifting );
}
mutex.unlock();
if ( !wait(500) ) {
if ( !wait(1000) ) {
terminate();
wait();
}
@ -469,14 +473,16 @@ void DVBout::process( unsigned char *buf, int size )
beginLive = !beginLive;
start();
}
if ( wDist<95 ) {
if ( wDist<wbufSize ) {
memcpy( wBuf+(wWrite*TS_SIZE*NTS), thBuf, TS_SIZE*NTS );
wpatpmt = patpmt;
++wDist;
++wWrite;
if ( wWrite>99 )
if ( wWrite==wbufSize )
wWrite = 0;
//fprintf(stderr,"WDIST = %d\n",wDist);
}
else {
fprintf(stderr,"Live ringbuffer full!! (%d)\n",wDist);
}
}
else if ( timeShifting ) {
@ -531,7 +537,7 @@ void DVBout::run()
{
if ( haveLive && fdPipe ) {
while ( haveLive && fdPipe ) {
if ( wDist>0 ) {
if ( wDist>5 ) {
if ( wpatpmt ) {
write( fdPipe, tspat, TS_SIZE );
write( fdPipe, tspmt, TS_SIZE );
@ -540,11 +546,12 @@ void DVBout::run()
write( fdPipe, wBuf+(wRead*TS_SIZE*NTS), TS_SIZE*NTS );
--wDist;
++wRead;
if ( wRead>99 )
if ( wRead==wbufSize )
wRead = 0;
}
else
else {
usleep( 100 );
}
}
return;
}

@ -44,7 +44,7 @@ public:
DVBout( ChannelDesc chan, int anum, int tnum, KaffeineDvbPlugin *p );
~DVBout();
void process( unsigned char *buf, int size );
bool goLive( const QString &name );
bool goLive( const QString &name, int ringBufSize );
void preStopLive();
void stopLive();
bool goBroadcast( Ts2Rtp *r );
@ -102,6 +102,7 @@ private:
int fileNumber;
QString fileName;
long long int fileMaxSize;
int wbufSize;
signals:

@ -45,7 +45,6 @@
#include <kxmlguifactory.h>
#include <kparts/componentfactory.h>
#include "kaffeineinput.h"
#include "kaffeinedvbplugin.h"
#include "dvbpanel.h"
#include "channeldesc.h"
@ -56,6 +55,12 @@
#define CHANICONSIZE 28
#define MODE_FREE 0
#define MODE_LIVE 100
#define MODE_BROADCAST 200
#define MODE_RECORD 300
#define MODE_CANTDO 400
DIconViewItem::DIconViewItem( DvbPanel *pan, QIconView *parent, const QString &text, const QPixmap &icon )
@ -1091,7 +1096,7 @@ void DvbPanel::setConfig()
void DvbPanel::showConfigDialog()
{
int ret;
int i, ret;
loop:
if ( !dvbConfig->haveData() ) {
@ -1104,7 +1109,9 @@ loop:
return;
}
DvbConfigDialog dlg( dvbConfig, mainWidget, plug );
for ( i=0; i<(int)dvb.count(); i++ )
dvb.at(i)->probeCam();
DvbConfigDialog dlg( this, dvbConfig, mainWidget, plug );
connect( dlg.dumpBtn, SIGNAL(clicked()), this, SLOT(dumpEvents()) );
ret = dlg.exec();
disconnect( dlg.dumpBtn, SIGNAL(clicked()), this, SLOT(dumpEvents()) );
@ -1112,6 +1119,14 @@ loop:
return;
rtp->setSocket( dvbConfig->broadcastAddress, dvbConfig->broadcastPort, dvbConfig->senderPort );
cleaner->setPaths( dvbConfig->shiftDir, dvbConfig->recordDir );
fillChannelList();
}
void DvbPanel::camClicked( int devNum )
{
dvb.at(devNum)->showCamDialog();
}
@ -1124,6 +1139,8 @@ QPtrList<Transponder> DvbPanel::getSourcesStatus()
Transponder t;
for ( i=0; i<(int)dvb.count(); i++ ) {
if ( !dvb.at(i)->getPriority() ) // priority==0==don't use
continue;
list = dvb.at(i)->getSources();
for ( j=0; j<(int)list.count(); j++ ) {
if ( dvb.at(i)->hasRec() || dvb.at(i)->hasBroadcast() )
@ -1176,7 +1193,7 @@ void DvbPanel::fillChannelList( ChannelDesc *ch )
}
else if ( currentCategory!="All" && chan->category!=currentCategory )
continue;
it = new KListViewItem( channelsCb, QString().sprintf("%04d", chan->num), chan->name, chan->tp.source );
it = new KListViewItem( channelsCb, QString().sprintf("%05d", chan->num), chan->name, chan->tp.source );
if ( ch && ch==chan )
visible = it;
it->setDragEnabled( true );
@ -1211,15 +1228,15 @@ void DvbPanel::fillChannelList( ChannelDesc *ch )
DvbStream* DvbPanel::getWorkingDvb( int mode, ChannelDesc *chan )
{
int i, ret;
QValueList<int> working; // notTuned=0, hasLive=1, hasBroadcast=2, hasRec=3, can'tDoChannel=4
QValueList<int> working; // free=0, hasLive=100, hasBroadcast=200, hasRec=300, can'tDoChannel=400
for ( i=0; i<(int)dvb.count(); i++ )
working.append( 0 );
working.append( 100-dvb.at(i)->getPriority() );
// fill in working status
for ( i=0; i<(int)dvb.count(); i++ ) {
if ( !dvb.at(i)->canSource( chan ) ) {
working[i] = 4;
if ( !dvb.at(i)->canSource( chan ) || working[i]==100 ) {
working[i] = MODE_CANTDO;
continue;
}
if ( dvb.at(i)->isTuned() ) {
@ -1227,14 +1244,18 @@ DvbStream* DvbPanel::getWorkingDvb( int mode, ChannelDesc *chan )
return dvb.at(i); // use that one since it's already tuned on the good mplex
}
else if ( dvb.at(i)->hasRec() )
working[i] = 3;
working[i] += MODE_RECORD;
else if ( dvb.at(i)->hasBroadcast() )
working[i] = 2;
else
working[i] = 1;
working[i] += MODE_BROADCAST;
else {
if ( mode==MODE_LIVE )
working[i] += MODE_FREE;
else
working[i] += MODE_LIVE;
}
}
else
working[i] = 0;
working[i] += MODE_FREE;
}
ret = 0;
// search for least working card
@ -1272,7 +1293,7 @@ void DvbPanel::setBroadcast()
return;
}
d = getWorkingDvb( 2, list.at(0) );
d = getWorkingDvb( MODE_BROADCAST, list.at(0) );
if ( d )
ret = d->canStartBroadcast( live, list.at(0) );
@ -1316,7 +1337,7 @@ void DvbPanel::checkTimers()
}
if ( !chan )
continue;
d = getWorkingDvb( 3, chan );
d = getWorkingDvb( MODE_RECORD, chan );
live = false;
if ( d )
ret = d->canStartTimer( live, chan );
@ -1826,7 +1847,7 @@ void DvbPanel::playLastChannel()
QTimer::singleShot( 2000, this, SLOT(playLastChannel()) );
return;
}
d = getWorkingDvb( 2, list.at(0) );
d = getWorkingDvb( MODE_BROADCAST, list.at(0) );
if ( d )
ret = d->canStartBroadcast( live, list.at(0) );
else
@ -1880,7 +1901,7 @@ void DvbPanel::next()
QListViewItem* nextItem;
QListViewItem* playingItem = channelsCb->findItem( QString().sprintf("%04d", dvbConfig->lastChannel), 0 );
QListViewItem* playingItem = channelsCb->findItem( QString().sprintf("%05d", dvbConfig->lastChannel), 0 );
if ( !playingItem == 0 ) // yes, it's in the current category
{
@ -1906,7 +1927,7 @@ void DvbPanel::previous()
QListViewItem* prevItem;
QListViewItem* playingItem = channelsCb->findItem( QString().sprintf("%04d", dvbConfig->lastChannel), 0 );
QListViewItem* playingItem = channelsCb->findItem( QString().sprintf("%05d", dvbConfig->lastChannel), 0 );
if ( !playingItem == 0 ) // yes, it's in the current category
{
@ -1927,19 +1948,14 @@ void DvbPanel::previous()
void DvbPanel::dvbZap( ChannelDesc *chan )
{
int i;
DvbStream *d=0;
DvbStream *d;
if ( currentFifo.isEmpty() || isTuning )
return;
isTuning = true;
emit setTimeShiftFilename( "" );
for ( i=0; i<(int)dvb.count(); i++ ) {
if ( dvb.at(i)->getCurrentTransponder()==chan->tp ) {
d = dvb.at(i);
break;
}
}
d = getWorkingDvb( MODE_LIVE, chan );
for ( i=0; i<(int)dvb.count(); i++ ) {
if ( dvb.at(i)->hasLive() ) {
dvb.at(i)->preStopLive();
@ -1973,40 +1989,20 @@ void DvbPanel::finalZap( DvbStream *d, ChannelDesc *chan )
{
QString s, t;
int i;
DvbStream *d1=d, *d2=0;
emit setCurrentPlugin( this );
fprintf( stderr, "Tuning to: %s / autocount: %lu\n", chan->name.latin1(), autocount );
QTime tm;
tm.start();
if ( !d1 ) {
for ( i=0; i<(int)dvb.count(); i++ ) {
if ( !dvb.at(i)->canSource( chan ) )
continue;
if ( dvb.at(i)->isTuned() ) {
if ( dvb.at(i)->getCurrentTransponder()==chan->tp ) {
d1 = dvb.at(i);
break;
}
else d2 = dvb.at(i);
}
else {
d1 = dvb.at(i);
break;
}
}
if ( !d1 && d2 )
d1 = d2;
}
if ( !d1 ) {
if ( !d ) {
emit dvbStop();
isTuning = false;
return;
}
int ret = d1->goLive( chan, currentFifo );
int ret = d->goLive( chan, currentFifo, dvbConfig->ringBufSize );
switch ( ret ) {
case DvbStream::ErrIsRecording :
@ -2045,7 +2041,7 @@ void DvbPanel::finalZap( DvbStream *d, ChannelDesc *chan )
resetSearch();
}
if ( d1->liveIsRecording() )
if ( d->liveIsRecording() )
recordBtn->setOn( true );
else
recordBtn->setOn( false );
@ -2255,6 +2251,8 @@ bool DvbPanel::getChannelList()
case 67 : chan->tp.coderateH = FEC_6_7; break;
case 78 : chan->tp.coderateH = FEC_7_8; break;
case 89 : chan->tp.coderateH = FEC_8_9; break;
case 35 : chan->tp.coderateH = FEC_3_5; break;
case 910 : chan->tp.coderateH = FEC_9_10; break;
case -1 : chan->tp.coderateH = FEC_AUTO;
}
s = s.right( s.length()-pos-1 );
@ -2275,6 +2273,9 @@ bool DvbPanel::getChannelList()
case 256 : chan->tp.modulation = QAM_256; break;
case 108 : chan->tp.modulation = VSB_8; break;
case 116 : chan->tp.modulation = VSB_16; break;
case 1000 : chan->tp.modulation = PSK_8; break;
case 1001 : chan->tp.modulation = APSK_16; break;
case 1003 : chan->tp.modulation = DQPSK; break;
case -1 : chan->tp.modulation = QAM_AUTO;
}
s = s.right( s.length()-pos-1 );
@ -2289,6 +2290,8 @@ bool DvbPanel::getChannelList()
case 67 : chan->tp.coderateL = FEC_6_7; break;
case 78 : chan->tp.coderateL = FEC_7_8; break;
case 89 : chan->tp.coderateL = FEC_8_9; break;
case 35 : chan->tp.coderateH = FEC_3_5; break;
case 910 : chan->tp.coderateH = FEC_9_10; break;
case -1 : chan->tp.coderateL = FEC_AUTO;
}
s = s.right( s.length()-pos-1 );
@ -2356,6 +2359,17 @@ bool DvbPanel::getChannelList()
s = s.right( s.length()-pos-1 );
pos = s.find("|");
chan->tp.nid = s.left(pos).toUShort();
s = s.right( s.length()-pos-1 );
pos = s.find("|");
switch ( s.left(pos).toInt() ) {
case 20 : chan->tp.rolloff = ROLLOFF_20; break;
case 25 : chan->tp.rolloff = ROLLOFF_25; break;
case 35 : chan->tp.rolloff = ROLLOFF_35; break;
case -1 : chan->tp.rolloff = ROLLOFF_AUTO;
}
s = s.right( s.length()-pos-1 );
pos = s.find("|");
chan->tp.S2 = s.left(pos).toInt();
if ( chan->tp.source.isEmpty() ) {
delete chan;
@ -2363,7 +2377,7 @@ bool DvbPanel::getChannelList()
}
chan->pix.load( dvbConfig->dvbConfigIconsDir+chan->name );
it = new KListViewItem( channelsCb, QString().sprintf("%04d", chan->num), chan->name, chan->tp.source );
it = new KListViewItem( channelsCb, QString().sprintf("%05d", chan->num), chan->name, chan->tp.source );
it->setDragEnabled( true );
if ( !chan->pix.isNull() )
it->setPixmap( 1, chan->pix );
@ -2467,6 +2481,8 @@ bool DvbPanel::saveChannelList()
case FEC_6_7 : tt<< "67|"; break;
case FEC_7_8 : tt<< "78|"; break;
case FEC_8_9 : tt<< "89|"; break;
case FEC_3_5 : tt<< "35|"; break;
case FEC_9_10 : tt<< "910|"; break;
case FEC_AUTO : tt<< "-1|";
}
switch ( chan->tp.inversion ) {
@ -2483,6 +2499,9 @@ bool DvbPanel::saveChannelList()
case QAM_256 : tt<< "256|"; break;
case VSB_8 : tt<< "108|"; break;
case VSB_16 : tt<< "116|"; break;
case PSK_8 : tt<< "1000|"; break;
case APSK_16 : tt<< "1001|"; break;
case DQPSK : tt<< "1003|"; break;
case QAM_AUTO : tt<< "-1|";
}
switch ( chan->tp.coderateL ) {
@ -2495,6 +2514,8 @@ bool DvbPanel::saveChannelList()
case FEC_6_7 : tt<< "67|"; break;
case FEC_7_8 : tt<< "78|"; break;
case FEC_8_9 : tt<< "89|"; break;
case FEC_3_5 : tt<< "35|"; break;
case FEC_9_10 : tt<< "910|"; break;
case FEC_AUTO : tt<< "-1|";
}
switch ( chan->tp.bandwidth ) {
@ -2533,7 +2554,15 @@ bool DvbPanel::saveChannelList()
}
tt<< "|";
tt<< chan->category+"|";
tt<< s.setNum(chan->tp.nid)+"|\n";
tt<< s.setNum(chan->tp.nid)+"|";
switch ( chan->tp.rolloff ) {
case ROLLOFF_20 : tt<< "20|"; break;
case ROLLOFF_25 : tt<< "25|"; break;
case ROLLOFF_35 : tt<< "35|"; break;
case ROLLOFF_AUTO : tt<< "-1|";
}
tt<< s.setNum(chan->tp.S2)+"|";
tt<< "\n";
}
ret = true;
f.close();

@ -42,13 +42,13 @@
#include "ts2rtp.h"
#include "cleaner.h"
#include "dvbevents.h"
#include "kaffeineinput.h"
class ChannelDesc;
class DvbStream;
class DvbPanel;
class KaffeineInput;
class KaffeineDvbPlugin;
@ -153,6 +153,7 @@ public slots:
void dvbNewTimer( QString name, QString channel, QString datetime, QString duration );
int getSNR( int device );
void diskStatus();
void camClicked( int devNum );
private:

@ -2,6 +2,7 @@
* dvbsi.cpp
*
* Copyright (C) 2003-2007 Christophe Thommeret <hftom@free.fr>
* Copyright (C) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
*
* 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
@ -30,7 +31,22 @@
#define TIMER_EVENT_SCAN_END 100
// These values are taken from ATSC A/65C Sec 5
#define PSIP_BASE_PID 0x1ffb
// This shouldn't be necessary, but at least the HVR-950 doesn't seem to
// find them in the time specified in the spec (needs more investigation)
#define CYCLE_TIME_FUDGEFACTOR 1000
// These values are taken from ATSC A/65C Sec 7.1
// (all values in ms)
#define PSIP_MAX_CYCLE_TIME_MGT 150 + CYCLE_TIME_FUDGEFACTOR
#define PSIP_MAX_CYCLE_TIME_VCT 400 + CYCLE_TIME_FUDGEFACTOR
// These values are taken from ATSC A/65C Sec 4.1
#define PSIP_TABLE_TYPE_MGT 0xc7
#define PSIP_TABLE_TYPE_TVCT 0xc8
#define PSIP_TABLE_TYPE_CVCT 0xc9
NitSection::NitSection( QPtrList<Transponder> *tp, bool *end, bool *ok, int anum, int tnum ) : KaffeineDVBsection( anum, tnum )
{
@ -158,6 +174,9 @@ bool NitSection::tableNIT( unsigned char* buf )
fprintf(stderr," Found frequency list.\n");
freqListDesc( buf, trans );
break;
case 0x79 :
S2satelliteDesc( buf, trans );
break;
default :
break;
}
@ -211,18 +230,53 @@ void NitSection::satelliteDesc( unsigned char* buf, Transponder *trans )
trans->pol = 'v';
else
trans->pol = 'h';
switch ( getBits(buf,70,2) ) {
case 0 : trans->modulation = QAM_AUTO; break;
case 1 : trans->modulation = QPSK; break;
case 2 : trans->modulation = PSK_8; break;
case 3 : trans->modulation = QAM_16; break;
}
s = t.setNum( getBits(buf,72,28), 16 );
trans->sr = s.toInt();
trans->sr /=10;
switch ( getBits(buf,100,4) ) {
case 0 : trans->coderateH = FEC_AUTO; break;
case 1 : trans->coderateH = FEC_1_2; break;
case 2 : trans->coderateH = FEC_2_3; break;
case 3 : trans->coderateH = FEC_3_4; break;
case 4 : trans->coderateH = FEC_5_6; break;
case 5 : trans->coderateH = FEC_7_8; break;
case 6 : trans->coderateH = FEC_8_9; break;
case 7 : trans->coderateH = FEC_NONE; break;
case 7 : trans->coderateH = FEC_3_5; break;
case 8 : trans->coderateH = FEC_4_5; break;
case 9 : trans->coderateH = FEC_9_10; break;
case 15 : trans->coderateH = FEC_NONE; break;
}
if ( getBits(buf,69,1) ) {
fprintf(stderr,"!!!!!!!!!!!!!!!!!! Found S2 MODULATION SYSTEM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
trans->S2 = 1;
switch ( getBits(buf,67,2) ) {
case 0 : trans->rolloff = ROLLOFF_35; break;
case 1 : trans->rolloff = ROLLOFF_25; break;
case 2 : trans->rolloff = ROLLOFF_20; break;
}
}
}
void NitSection::S2satelliteDesc( unsigned char* buf, Transponder *trans )
{
fprintf(stderr,"!!!!!!!!!!!!!!!!!! Found S2 DESCRIPTOR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
int scrambling_sequence_selector = getBits(buf,16,1);
int multiple_input_stream_flag = getBits(buf,17,1);
int backwards_compatibility_indicator = getBits(buf,18,1);
int scrambling_sequence_index = 0;
if ( scrambling_sequence_selector )
scrambling_sequence_index = getBits(buf,30,18);
int input_stream_identifier = 0;
if ( multiple_input_stream_flag )
input_stream_identifier = getBits(buf,48,8);
}
@ -246,13 +300,17 @@ void NitSection::cableDesc( unsigned char* buf, Transponder *trans )
trans->sr = s.toInt();
trans->sr /=10;
switch ( getBits(buf,100,4) ) {
case 0 : trans->coderateH = FEC_AUTO; break;
case 1 : trans->coderateH = FEC_1_2; break;
case 2 : trans->coderateH = FEC_2_3; break;
case 3 : trans->coderateH = FEC_3_4; break;
case 4 : trans->coderateH = FEC_5_6; break;
case 5 : trans->coderateH = FEC_7_8; break;
case 6 : trans->coderateH = FEC_8_9; break;
case 7 : trans->coderateH = FEC_NONE; break;
case 7 : trans->coderateH = FEC_3_5; break;
case 8 : trans->coderateH = FEC_4_5; break;
case 9 : trans->coderateH = FEC_9_10; break;
case 15 : trans->coderateH = FEC_NONE; break;
}
}
@ -456,6 +514,7 @@ bool DVBsi::tablePMT( unsigned char* buf )
while ( length>4 ) {
audio=ac3=false;
lang="";
type = getBits(buf,0,8);
pid = getBits(buf,11,13);
if ( type==1/*mpeg1*/ || type==2/*mpeg2*/ || type==16/*mpeg4*/ || type==27/*h264*/ ) {
@ -466,6 +525,11 @@ bool DVBsi::tablePMT( unsigned char* buf )
if ( type==3 || type==4 ) {
audio = true;
}
if (type == 0x81) {
// AC3 was added in ATSC A/52B (See A3.1 "Stream Type")
audio = true;
ac3 = true;
}
loop = getBits(buf,28,12);
buf +=5;
length -=(5+loop);
@ -499,6 +563,7 @@ bool DVBsi::tablePMT( unsigned char* buf )
}
break;
case 0x6a :
case 0x81 :
audio = true;
ac3 = true;
break;
@ -637,7 +702,204 @@ bool DVBsi::getSection( int pid, int tid, int timeout, int sid )
return true;
}
bool DVBsi::parseMGT( int pid, int tid, int timeout, int sid )
{
unsigned char buf[4096];
int n=0;
int skip=0;
bool vct_found = false;
fprintf(stderr, "parseMGT called for 0x%02x 0x%02x\n", pid, tid);
if ( !setFilter( pid, tid, timeout ) )
return false;
if ( poll(pf,1,timeout)>0 ){
if ( pf[0].revents & POLLIN ){
n = read( fdDemux, buf, 4096 );
skip = 0;
}
else
skip++;
}
else
skip++;
if ( skip || n<4 ) {
fprintf(stderr,"\nInvalid section length or timeout: pid=%d\n\n", pid);
stopFilter();
return false;
}
// Parse the Master Guide Table Section
unsigned int protocol_version = getBits(buf,64,8);
unsigned int tables_defined = getBits(buf,72,16);
fprintf(stderr, "protocol_version = %d\n", protocol_version);
fprintf(stderr, "tables_defined = %d\n", tables_defined);
// Now let's go through the table entries....
unsigned char *t_entry = &buf[88/8];
for (unsigned int t = 0; t < tables_defined; t++) {
unsigned int table_type;
unsigned int table_pid;
unsigned int table_version_number;
unsigned int table_number_bytes;
unsigned int table_number_des_length;
table_type = getBits(t_entry, 0, 16);
table_pid = getBits(t_entry, 19, 13);
table_version_number = getBits(t_entry, 35, 5);
table_number_bytes = getBits(t_entry, 40, 32);
table_number_des_length = getBits(t_entry, 76, 12);
fprintf(stderr,
"MGT entry type=0x%04x pid=0x%04x ver=%d sz=%d\n",
table_type, table_pid, table_version_number,
table_number_bytes);
if (table_type == 0x0000 || table_type == 0x0001) {
// TVCT table found
vct_table = PSIP_TABLE_TYPE_TVCT;
vct_found = true;
} else if (table_type == 0x0002 ||
table_type == 0x0003) {
// CVCT table found
vct_table = PSIP_TABLE_TYPE_CVCT;
vct_found = true;
}
t_entry += (11 + table_number_des_length);
}
stopFilter();
return vct_found;
}
bool DVBsi::parseVCT( int pid, int tid, int timeout, int sid )
{
unsigned char buf[4096];
int n=0;
int skip=0;
fprintf(stderr, "parseVCT called for 0x%02x 0x%02x\n", pid, tid);
if ( !setFilter( pid, tid, timeout ) )
return false;
if ( poll(pf,1,timeout)>0 ){
if ( pf[0].revents & POLLIN ){
n = read( fdDemux, buf, 4096 );
skip = 0;
}
else
skip++;
}
else
skip++;
if ( skip || n<4 ) {
fprintf(stderr,"\nInvalid section length or timeout: pid=%d\n\n", pid);
stopFilter();
return false;
}
// Parse the Virtual Channel Table Section
unsigned int protocol_version = getBits(buf,64,8);
unsigned int num_channels = getBits(buf,72,8);
fprintf(stderr, "protocol_version = %d\n", protocol_version);
fprintf(stderr, "num_channels = %d\n", num_channels);
// Now let's go through the table entries....
unsigned char *t_entry = &buf[80/8];
for (unsigned int t = 0; t < num_channels; t++) {
char short_name[8];
unsigned int major_channel_num;
unsigned int minor_channel_num;
unsigned int modulation_mode;
unsigned int channel_tsid;
unsigned int program_number;
unsigned int access_controlled;
unsigned int hidden;
unsigned int service_type;
unsigned int source_id;
unsigned int reserved;
unsigned int descriptors_length;
// Short name
// Yes, I need a real UCS-2 to UTF-8 conversion here...
memset(short_name, 0, sizeof(short_name));
snprintf(short_name, sizeof(short_name), "%c%c%c%c%c%c%c",
t_entry[1],t_entry[3],t_entry[5],t_entry[7],
t_entry[9],t_entry[11],t_entry[13]);
reserved = getBits(t_entry, 112, 4);
major_channel_num = getBits(t_entry, 116, 10);
minor_channel_num = getBits(t_entry, 126, 10);
modulation_mode = getBits(t_entry, 136, 8);
channel_tsid = getBits(t_entry, 176, 16);
program_number = getBits(t_entry, 192, 16);
access_controlled = getBits(t_entry, 210, 1);
hidden = getBits(t_entry, 211, 1);
service_type = getBits(t_entry, 218, 6);
source_id = getBits(t_entry, 224, 16);
reserved = getBits(t_entry, 240, 6);
descriptors_length = getBits(t_entry, 246, 10);
fprintf(stderr, "short name=%s\n", short_name);
fprintf(stderr, "reserved=0x%04x\n", reserved);
fprintf(stderr, "major=%d\n", major_channel_num);
fprintf(stderr, "minor=%d\n", minor_channel_num);
fprintf(stderr, "modulation mode=0x%02x\n", modulation_mode);
fprintf(stderr, "channel_tsid=0x%04x\n", channel_tsid);
fprintf(stderr, "program_number=0x%04x\n", program_number);
fprintf(stderr, "access_controlled=0x%01x\n", access_controlled);
fprintf(stderr, "hidden=0x%01x\n", hidden);
fprintf(stderr, "service_type=0x%02x\n", service_type);
fprintf(stderr, "source_id=0x%04x\n", source_id);
fprintf(stderr, "des length=%d\n", descriptors_length);
ChannelDesc *desc = new ChannelDesc();
desc->tp.tsid = channel_tsid;
desc->name = QString("%1-%2 %3").arg(major_channel_num).arg(minor_channel_num).arg(short_name);
desc->sid = program_number;
if (access_controlled == 1)
desc->fta = 1;
else
desc->fta = 0; // 0 for free
// Algorithm taken from ATSC A/65C Sec 4.2
// However, the algorithm doesn't appear correct, as it
// truncates out data. For example, both 68-1 and 4-1 would
// yield the same one_part_number
desc->num = (major_channel_num << 10) + minor_channel_num;
fprintf(stderr, "channel num=%d\n", desc->num);
// ATSC A/65C Sec 6.3.1 Table 6.7
if (service_type == 0x01) {
// Analog television (not supported)
} else if (service_type == 0x02) {
// ATSC Video
desc->type = 1;
} else if (service_type == 0x03) {
// ATSC Audio
desc->type = 2;
} else if (service_type == 0x02) {
// ATSC Data only service (not supported)
} else if (service_type > 0x05 && service_type < 0x3f) {
// Reserved (not supported)
} else {
// Unknown
}
// Now add the new channel to the list (if supported)
if ((desc->type == 1 || desc->type == 2) && hidden == 0) {
channels.append( desc );
} else {
fprintf(stderr, "Not adding channel\n");
delete desc;
}
// Advance to the next entry
t_entry += (32 + descriptors_length);
}
stopFilter();
return true;
}
void DVBsi::stop()
{
@ -701,7 +963,24 @@ void DVBsi::timerEvent( QTimerEvent *e )
}
}
// See ATSC standard A/65c for info on PSIP and what all these acronyms are...
bool DVBsi::handle_atsc_transponder() {
// Loop through the MGT to get the list of PIDS for virtual channels
if (parseMGT(PSIP_BASE_PID, PSIP_TABLE_TYPE_MGT,
PSIP_MAX_CYCLE_TIME_MGT) == false) {
// We couldn't find the MGT
fprintf(stderr, "Could not find MGT in stream. Cannot continue\n");
return false;
};
// Now look at the TVCT for info on the individual channels found
if (parseVCT(PSIP_BASE_PID, vct_table,
PSIP_MAX_CYCLE_TIME_VCT) == false) {
fprintf(stderr, "Could not parse VCT in stream. Cannot continue\n");
return false;
}
return true;
}
void DVBsi::run()
{
@ -744,12 +1023,22 @@ void DVBsi::run()
indexChannels = j;
fprintf(stderr,"Transponders: %d/%d\n", i+1, transponders.count() );
if ( scanMode ) {
nitEnded = false;
ns = new NitSection( &transponders, &nitEnded, &ok, adapter, tuner ); //NIT
fprintf(stderr,"scanMode=%d\n", scanMode);
if ( chan.tp.type == FE_ATSC ) {
// Separate out the ATSC scanning so that we
// don't interfere with existing DVB support
if (!handle_atsc_transponder())
continue;
}
else {
printf("it's dvb %d!\n", chan.tp.type);
if ( scanMode ) {
nitEnded = false;
ns = new NitSection( &transponders, &nitEnded, &ok, adapter, tuner ); //NIT
}
getSection( 0x11, 0x42 ); //SDT
}
if ( !getSection( 0x11, 0x42 ) ) //SDT
continue;
if ( !isRunning ) {
out();
return;
@ -822,7 +1111,7 @@ void DVBsi::run()
}
// !!!! only there for debugging !!!!!!!!!!
bool DVBsi::listChannels()
{
QString s,t;

@ -36,6 +36,7 @@ public:
bool getSection( int pid, int tid, int timeout=5000 );
bool tableNIT( unsigned char* buf );
void satelliteDesc( unsigned char* buf, Transponder *trans );
void S2satelliteDesc( unsigned char* buf, Transponder *trans );
void cableDesc( unsigned char* buf, Transponder *trans );
void terrestrialDesc( unsigned char* buf, Transponder *trans );
void freqListDesc( unsigned char* buf, Transponder *trans );
@ -66,6 +67,11 @@ public:
bool tablePMT( unsigned char* buf );
void serviceDesc( unsigned char* buf, ChannelDesc *desc );
// ATSC related methods
virtual bool handle_atsc_transponder();
virtual bool parseMGT( int pid, int tid, int timeout=5000, int sid=0 );
virtual bool parseVCT( int pid, int tid, int timeout=5000, int sid=0 );
QPtrList<ChannelDesc> channels;
QPtrList<Transponder> transponders;
DvbStream *dvb;
@ -90,6 +96,9 @@ private:
int scanMode;
NitSection *ns;
/* ATSC related */
int vct_table;
signals:
void end( bool );

@ -43,6 +43,7 @@
#include <klocale.h>
#include <kapplication.h>
#include <kmessagebox.h>
#include "dvbstream.h"
#include "dvbevents.h"
@ -100,13 +101,23 @@ void DvbStream::probeCam()
int ci_type=0;
if ( camProbed )
return;
if ( (ci_type=DvbCam::probe( dvbDevice->adapter, 0 ))>0 )
cam = new DvbCam( dvbDevice->adapter, 0, dvbDevice->tuner, ci_type );
if ( (ci_type=DvbCam::probe( dvbDevice->adapter, 0 ))>0 ) {
cam = new DvbCam( dvbDevice->adapter, 0, dvbDevice->tuner, ci_type, dvbDevice->camMaxService );
dvbDevice->hasCAM = true;
}
camProbed = true;
}
void DvbStream::showCamDialog()
{
if ( cam )
dvbDevice->camMaxService = cam->showCamDialog();
}
QStringList DvbStream::getSources( bool all )
{
if ( !all ) {
@ -143,6 +154,8 @@ bool DvbStream::canSource( ChannelDesc *chan )
else
return false;
}
if ( chan->tp.S2 && !dvbDevice->doS2 )
return false;
int i;
for ( i=0; i<dvbDevice->numLnb; i++ ) {
if ( dvbDevice->lnb[i].source.contains(chan->tp.source) )
@ -153,6 +166,13 @@ bool DvbStream::canSource( ChannelDesc *chan )
int DvbStream::getPriority()
{
return dvbDevice->priority;
}
int DvbStream::getSatPos( const QString &src )
{
int i;
@ -174,7 +194,7 @@ bool DvbStream::openFe()
fprintf(stderr,"openFe: fdFrontend != 0\n");
return false;
}
fdFrontend = open( frontendName.ascii(), O_RDWR );
fdFrontend = open( frontendName.ascii(), O_RDWR /*| O_NONBLOCK*/ );
if ( fdFrontend<0 ) {
perror("openFe:");
fdFrontend = 0;
@ -308,7 +328,6 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
{
unsigned long lof=0;
int res, hiband=0;
struct dvb_frontend_parameters feparams;
struct dvb_frontend_info fe_info;
fe_status_t status;
unsigned long freq=chan->tp.freq;
@ -317,6 +336,14 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
int rotorMove = 0;
int loop=0, i;
struct dtv_property cmdargs[20];
struct dtv_properties cmdseq;
int inversion;
int bandwidth;
if ( chan->tp.S2 && !dvbDevice->doS2 )
return false;
closeFe();
if ( !openFe() )
return false;
@ -333,18 +360,45 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
freq*=1000;
srate*=1000;
QTime t1 = QTime::currentTime();
if ( chan->tp.inversion==INVERSION_AUTO ) {
if ( fe_info.caps & FE_CAN_INVERSION_AUTO )
inversion = chan->tp.inversion;
else {
fprintf(stderr,"Can NOT inversion_auto\n");
inversion = INVERSION_OFF;
}
}
else
inversion=chan->tp.inversion;
switch( fe_info.type ) {
case FE_OFDM : {
QString s = fe_info.name;
//if ( s.contains("TerraTec/qanu USB2.0 Highspeed DVB-T Receiver") ) // cinergyT2 hack
// freq+=167000;
if (freq < 1000000)
freq*=1000UL;
feparams.frequency=freq;
feparams.u.ofdm.bandwidth=chan->tp.bandwidth;
feparams.u.ofdm.code_rate_HP=chan->tp.coderateH;
feparams.u.ofdm.code_rate_LP=chan->tp.coderateL;
feparams.u.ofdm.constellation=chan->tp.modulation;
feparams.u.ofdm.transmission_mode=chan->tp.transmission;
feparams.u.ofdm.guard_interval=chan->tp.guard;
feparams.u.ofdm.hierarchy_information=chan->tp.hierarchy;
cmdargs[0].cmd = DTV_DELIVERY_SYSTEM; cmdargs[0].u.data = SYS_DVBT;
cmdargs[1].cmd = DTV_FREQUENCY; cmdargs[1].u.data = freq;
cmdargs[2].cmd = DTV_MODULATION; cmdargs[2].u.data = chan->tp.modulation;
cmdargs[3].cmd = DTV_CODE_RATE_HP; cmdargs[3].u.data = chan->tp.coderateH;
cmdargs[4].cmd = DTV_CODE_RATE_LP; cmdargs[4].u.data = chan->tp.coderateL;
cmdargs[5].cmd = DTV_GUARD_INTERVAL; cmdargs[5].u.data = chan->tp.guard;
cmdargs[6].cmd = DTV_TRANSMISSION_MODE; cmdargs[6].u.data = chan->tp.transmission;
cmdargs[7].cmd = DTV_HIERARCHY; cmdargs[7].u.data = chan->tp.hierarchy;
if ( chan->tp.bandwidth==BANDWIDTH_8_MHZ )
bandwidth = 8000000;
else if ( chan->tp.bandwidth==BANDWIDTH_7_MHZ )
bandwidth = 7000000;
else if ( chan->tp.bandwidth==BANDWIDTH_6_MHZ )
bandwidth = 6000000;
cmdargs[8].cmd = DTV_BANDWIDTH_HZ; cmdargs[8].u.data = bandwidth;
cmdargs[9].cmd = DTV_INVERSION; cmdargs[9].u.data = inversion;
cmdargs[10].cmd = DTV_TUNE;
cmdseq.num = 11;
cmdseq.props = cmdargs;
fprintf(stderr,"tuning DVB-T to %lu Hz\n", freq);
fprintf(stderr,"inv:%d bw:%d fecH:%d fecL:%d mod:%d tm:%d gi:%d hier:%d\n", chan->tp.inversion,
chan->tp.bandwidth, chan->tp.coderateH, chan->tp.coderateL, chan->tp.modulation,
@ -352,11 +406,16 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
break;
}
case FE_QAM : {
cmdargs[0].cmd = DTV_DELIVERY_SYSTEM; cmdargs[0].u.data = SYS_DVBC_ANNEX_AC;
cmdargs[1].cmd = DTV_FREQUENCY; cmdargs[1].u.data = freq;
cmdargs[2].cmd = DTV_MODULATION; cmdargs[2].u.data = chan->tp.modulation;
cmdargs[3].cmd = DTV_SYMBOL_RATE; cmdargs[3].u.data = srate;
cmdargs[4].cmd = DTV_INNER_FEC; cmdargs[4].u.data = chan->tp.coderateH;
cmdargs[5].cmd = DTV_INVERSION; cmdargs[5].u.data = inversion;
cmdargs[6].cmd = DTV_TUNE;
cmdseq.num = 7;
cmdseq.props = cmdargs;
fprintf(stderr,"tuning DVB-C to %lu\n", freq);
feparams.frequency=freq;
feparams.u.qam.symbol_rate = srate;
feparams.u.qam.fec_inner = chan->tp.coderateH;
feparams.u.qam.modulation = chan->tp.modulation;
fprintf(stderr,"inv:%d sr:%lu fecH:%d mod:%d\n", chan->tp.inversion,
srate, chan->tp.coderateH, chan->tp.modulation );
break;
@ -384,51 +443,78 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
lof = (dvbDevice->lnb[lnbPos].loFreq*1000);
}
if ( freq<lof )
feparams.frequency = ( lof-freq );
freq = ( lof-freq );
else
feparams.frequency = ( freq-lof );
freq = ( freq-lof );
}
else
feparams.frequency=freq;
feparams.u.qpsk.symbol_rate=srate;
feparams.u.qpsk.fec_inner=chan->tp.coderateH;
fprintf(stderr,"inv:%d fecH:%d\n", chan->tp.inversion, chan->tp.coderateH );
fprintf(stderr,"inv:%d fecH:%d mod:%d\n", chan->tp.inversion, chan->tp.coderateH, chan->tp.modulation );
if ( setDiseqc( lnbPos, chan, hiband, rotorMove, dvr )!=0 ) {
closeFe();
return false;
}
fprintf( stderr, "Diseqc settings time = %d ms\n", t1.msecsTo( QTime::currentTime() ) );
t1 = QTime::currentTime();
if ( chan->tp.S2 ) {
fprintf(stderr,"\nTHIS IS DVB-S2 >>>>>>>>>>>>>>>>>>>\n");
cmdargs[0].cmd = DTV_DELIVERY_SYSTEM; cmdargs[0].u.data = SYS_DVBS2;
cmdargs[1].cmd = DTV_FREQUENCY; cmdargs[1].u.data = freq;
cmdargs[2].cmd = DTV_MODULATION; cmdargs[2].u.data = chan->tp.modulation;
cmdargs[3].cmd = DTV_SYMBOL_RATE; cmdargs[3].u.data = srate;
cmdargs[4].cmd = DTV_INNER_FEC; cmdargs[4].u.data = chan->tp.coderateH;
cmdargs[5].cmd = DTV_PILOT; cmdargs[5].u.data = PILOT_AUTO;
cmdargs[6].cmd = DTV_ROLLOFF; cmdargs[6].u.data = chan->tp.rolloff;
cmdargs[7].cmd = DTV_INVERSION; cmdargs[7].u.data = inversion;
cmdargs[8].cmd = DTV_TUNE;
cmdseq.num = 9;
cmdseq.props = cmdargs;
}
else {
cmdargs[0].cmd = DTV_DELIVERY_SYSTEM; cmdargs[0].u.data = SYS_DVBS;
cmdargs[1].cmd = DTV_FREQUENCY; cmdargs[1].u.data = freq;
cmdargs[2].cmd = DTV_MODULATION; cmdargs[2].u.data = chan->tp.modulation;
if ( chan->tp.modulation==QAM_AUTO )
cmdargs[2].u.data = QPSK;
cmdargs[3].cmd = DTV_SYMBOL_RATE; cmdargs[3].u.data = srate;
cmdargs[4].cmd = DTV_INNER_FEC; cmdargs[4].u.data = chan->tp.coderateH;
cmdargs[5].cmd = DTV_INVERSION; cmdargs[5].u.data = inversion;
cmdargs[6].cmd = DTV_TUNE;
cmdseq.num = 7;
cmdseq.props = cmdargs;
}
break;
}
case FE_ATSC : {
cmdargs[0].cmd = DTV_DELIVERY_SYSTEM; cmdargs[0].u.data = SYS_ATSC;
cmdargs[1].cmd = DTV_FREQUENCY; cmdargs[1].u.data = freq;
cmdargs[2].cmd = DTV_MODULATION; cmdargs[2].u.data = chan->tp.modulation;
cmdargs[3].cmd = DTV_INVERSION; cmdargs[3].u.data = inversion;
cmdargs[4].cmd = DTV_TUNE;
cmdseq.num = 5;
cmdseq.props = cmdargs;
fprintf(stderr,"tuning ATSC to %lu\n", freq);
feparams.frequency=freq;
feparams.u.vsb.modulation = chan->tp.modulation;
fprintf(stderr,"inv:%d mod:%d\n", chan->tp.inversion, chan->tp.modulation );
break;
}
}
if ( chan->tp.inversion==INVERSION_AUTO ) {
if ( fe_info.caps & FE_CAN_INVERSION_AUTO )
feparams.inversion=chan->tp.inversion;
else {
fprintf(stderr,"Can NOT inversion_auto\n");
feparams.inversion=INVERSION_OFF;
}
}
else
feparams.inversion=chan->tp.inversion;
if ( rotorMove )
if ( rotorMove ) {
if ( ioctl( fdFrontend, FE_SET_PROPERTY, &cmdseq )<0 ) {
perror("ERROR tuning\n");
closeFe();
return false;
}
moveRotor( lnbPos, chan, hiband, dvr );
loop = 2;
}
while ( loop>-1 ) {
if (ioctl(fdFrontend,FE_SET_FRONTEND,&feparams) < 0) {
perror("ERROR tuning \n");
if ( ioctl( fdFrontend, FE_SET_PROPERTY, &cmdseq )<0 ) {
perror("ERROR tuning\n");
closeFe();
return false;
}
for ( i=0; i<(dvbDevice->tuningTimeout/100); i++ ) {
QTime lockTime = QTime::currentTime();
do {
usleep( 100000 );
fprintf( stderr, "." );
if ( ioctl( fdFrontend, FE_READ_STATUS, &status )==-1 ) {
@ -440,7 +526,7 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
loop = 0;
break;
}
}
} while ( lockTime.msecsTo( QTime::currentTime() )<=dvbDevice->tuningTimeout );
fprintf(stderr,"\n");
--loop;
}
@ -451,6 +537,8 @@ bool DvbStream::tuneDvb( ChannelDesc *chan, bool dvr )
return false;
}
fprintf( stderr, "Tuning time = %d ms\n", t1.msecsTo( QTime::currentTime() ) );
if ( rotorMove )
dvbDevice->lnb[lnbPos].currentSource = chan->tp.source;
@ -496,6 +584,23 @@ int DvbStream::setDiseqc( int switchPos, ChannelDesc *chan, int hiband, int &rot
int i;
int voltage18 = ( (chan->tp.pol=='H')||(chan->tp.pol=='h') );
int ci = 4 * switchPos + 2 * hiband + (voltage18 ? 1 : 0);
bool secMini = false;
bool hasRotor = false;
bool hasSwitch = true;
if ( dvbDevice->numLnb<2 )
hasSwitch = false;
if ( dvbDevice->lnb[switchPos].rotorType!=0 && dvbDevice->lnb[switchPos].rotorType!=3 )
hasRotor = true;
if ( dvbDevice->numLnb==2 && dvbDevice->secMini )
secMini = true;
if ( dvbDevice->secTwice )
diseqcTwice = 2;
else
diseqcTwice = 1;
fprintf( stderr, "DiSEqC: switch pos %i, %sV, %sband (index %d)\n", switchPos, voltage18 ? "18" : "13", hiband ? "hi" : "lo", ci );
if ( ci < 0 || ci >= (int)(sizeof(switchCmd)/sizeof(struct dvb_diseqc_master_cmd)) )
@ -507,85 +612,108 @@ int DvbStream::setDiseqc( int switchPos, ChannelDesc *chan, int hiband, int &rot
if ( ioctl(fdFrontend, FE_SET_VOLTAGE, ci%2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13) )
perror("FE_SET_VOLTAGE failed");
fprintf( stderr, "DiSEqC: %02x %02x %02x %02x %02x %02x\n", switchCmd[ci].msg[0], switchCmd[ci].msg[1], switchCmd[ci].msg[2], switchCmd[ci].msg[3], switchCmd[ci].msg[4], switchCmd[ci].msg[5] );
for ( i=0; i<2; ++i ) {
usleep(15*1000);
if ( ioctl(fdFrontend, FE_DISEQC_SEND_MASTER_CMD, &switchCmd[ci]) )
perror("FE_DISEQC_SEND_MASTER_CMD failed");
}
QString msg;
if ( dvbDevice->lnb[switchPos].rotorType!=0 && chan->tp.source!=dvbDevice->lnb[switchPos].currentSource ) {
int i, index=-1;
double angle=0.0, oldAngle=0.0;
fprintf( stderr, "Driving rotor to %s\n", chan->tp.source.ascii() );
for ( i=0; i<(int)dvbDevice->lnb[switchPos].source.count(); i++ ) {
if ( dvbDevice->lnb[switchPos].source[i]==chan->tp.source ) {
index = i;
break;
if ( hasSwitch ) {
if ( !secMini ) {
fprintf( stderr, "DiSEqC: %02x %02x %02x %02x %02x %02x\n", switchCmd[ci].msg[0], switchCmd[ci].msg[1], switchCmd[ci].msg[2], switchCmd[ci].msg[3], switchCmd[ci].msg[4], switchCmd[ci].msg[5] );
for ( i=0; i<diseqcTwice; ++i ) {
usleep(15*1000);
if ( ioctl(fdFrontend, FE_DISEQC_SEND_MASTER_CMD, &switchCmd[ci]) )
perror("FE_DISEQC_SEND_MASTER_CMD failed");
}
}
angle = getSourceAngle( chan->tp.source );
if ( dvbDevice->lnb[switchPos].rotorType==1 ) {
fprintf( stderr, "Rotor: gotoX=%f\n", angle );
gotoX( angle );
}
else {
int pos = dvbDevice->lnb[switchPos].position[index];
fprintf( stderr, "Rotor: gotoN=%d\n", pos );
rotorCommand( 9, pos );
}
if ( dvbDevice->lnb[switchPos].currentSource.isEmpty() ) {
rotor = 10;
msg = i18n("Moving rotor from unknown position...");
}
else {
oldAngle = getSourceAngle( dvbDevice->lnb[switchPos].currentSource );
fprintf( stderr, "old rotor pos: %f °\n", oldAngle );
fprintf( stderr, "new rotor pos: %f °\n", angle );
angle = fabs(angle-oldAngle);
fprintf( stderr, "Rotation angle: %f °\n", angle );
if ( voltage18 )
rotor = (int)(angle*dvbDevice->lnb[switchPos].speed18v)+1;
else
rotor = (int)(angle*dvbDevice->lnb[switchPos].speed13v)+1;
msg = i18n("Moving rotor...");
fprintf( stderr, "DiSEqC: mini_diseqc\n" );
for ( i=0; i<diseqcTwice; ++i ) {
usleep(15*1000);
if ( ioctl(fdFrontend, FE_DISEQC_SEND_BURST, (ci/4)%2 ? SEC_MINI_B : SEC_MINI_A) )
perror("FE_DISEQC_SEND_BURST failed");
}
}
fprintf( stderr, "Rotation time: %d sec.\n", rotor );
}
if ( rotor ) {
int j;
if ( !dvr ) {
for ( j=0; j<(rotor*2); j++ ) {
usleep( 500000 );
}
if ( hasRotor && chan->tp.source!=dvbDevice->lnb[switchPos].currentSource ) {
rotor = 1;
return 0;
}
if ( (ci/2)%2 ) {
usleep(15*1000);
if ( ioctl(fdFrontend, FE_SET_TONE, SEC_TONE_ON) )
perror("FE_SET_TONE failed");
}
return 0;
}
void DvbStream::moveRotor( int switchPos, ChannelDesc *chan, int hiband, bool dvr )
{
int i, j, index=-1;
double angle=0.0, oldAngle=0.0;
int rotor=0;
int voltage18 = ( (chan->tp.pol=='H')||(chan->tp.pol=='h') );
int ci = 4 * switchPos + 2 * hiband + (voltage18 ? 1 : 0);
QString msg;
fprintf( stderr, "Driving rotor to %s\n", chan->tp.source.ascii() );
for ( i=0; i<(int)dvbDevice->lnb[switchPos].source.count(); i++ ) {
if ( dvbDevice->lnb[switchPos].source[i]==chan->tp.source ) {
index = i;
break;
}
else {
QProgressDialog progress( msg, i18n("Cancel"), rotor*2, 0, "progress", true );
for ( j=0; j<(rotor*2); j++ ) {
progress.setProgress( j );
qApp->processEvents();
if ( progress.wasCanceled() )
break;
usleep( 500000 );
}
progress.setProgress( rotor*2 );
}
angle = getSourceAngle( chan->tp.source );
if ( dvbDevice->lnb[switchPos].rotorType==1 ) {
fprintf( stderr, "Rotor: gotoX=%f\n", angle );
gotoX( angle );
}
else {
int pos = dvbDevice->lnb[switchPos].position[index];
fprintf( stderr, "Rotor: gotoN=%d\n", pos );
rotorCommand( 9, pos );
}
if ( dvbDevice->lnb[switchPos].currentSource.isEmpty() ) {
rotor = 10;
msg = i18n("Moving rotor from unknown position...");
}
else {
oldAngle = getSourceAngle( dvbDevice->lnb[switchPos].currentSource );
fprintf( stderr, "old rotor pos: %f °\n", oldAngle );
fprintf( stderr, "new rotor pos: %f °\n", angle );
angle = fabs(angle-oldAngle);
fprintf( stderr, "Rotation angle: %f °\n", angle );
if ( voltage18 )
rotor = (int)(angle*dvbDevice->lnb[switchPos].speed18v)+1;
else
rotor = (int)(angle*dvbDevice->lnb[switchPos].speed13v)+1;
msg = i18n("Moving rotor...");
}
fprintf( stderr, "Rotation time: %d sec.\n", rotor );
if ( !dvr ) {
for ( j=0; j<(rotor*2); j++ ) {
usleep( 500000 );
}
}
else {
QProgressDialog progress( msg, i18n("Cancel"), rotor*2, 0, "progress", true );
for ( j=0; j<(rotor*2); j++ ) {
progress.setProgress( j );
qApp->processEvents();
if ( progress.wasCanceled() )
break;
usleep( 500000 );
}
progress.setProgress( rotor*2 );
qApp->processEvents();
}
for ( i=0; i<2; ++i ) {
if ( (ci/2)%2 ) {
usleep(15*1000);
if ( ioctl(fdFrontend, FE_DISEQC_SEND_BURST, (ci/4)%2 ? SEC_MINI_B : SEC_MINI_A) )
perror("FE_DISEQC_SEND_BURST failed");
if ( ioctl(fdFrontend, FE_SET_TONE, SEC_TONE_ON) )
perror("FE_SET_TONE failed");
}
usleep(15*1000);
if ( ioctl(fdFrontend, FE_SET_TONE, (ci/2)%2 ? SEC_TONE_ON : SEC_TONE_OFF) )
perror("FE_SET_TONE failed");
return 0;
}
@ -681,7 +809,7 @@ void DvbStream::rotorCommand( int cmd, int n1, int n2, int n3 )
};
int i;
for ( i=0; i<2; ++i ) {
for ( i=0; i<diseqcTwice; ++i ) {
usleep(15*1000);
if ( ioctl( fdFrontend, FE_DISEQC_SEND_MASTER_CMD, &cmds[cmd] ) )
perror("Rotor : FE_DISEQC_SEND_MASTER_CMD failed");
@ -803,28 +931,33 @@ bool DvbStream::hasVideo()
void DvbStream::run()
{
unsigned char buf[188];
int READSIZE = 188*20;
int BUFSIZE = 188*100;
int WSIZE = 188*64;
unsigned char buf[READSIZE];
unsigned char thBuf[BUFSIZE];
int n, i, thWrite=0;
int WSIZE=188*8;
DVBout *o=0;
signal( SIGPIPE, SIG_IGN );
while ( isRunning ) {
if ( poll( &pfd, 1, 100 ) ) {
n = read( fdDvr, buf, 188 );
if ( n==188 ) {
n = read( fdDvr, buf, READSIZE );
if ( n && !(n%188) ) {
//fprintf( stderr, "DVR0: read : %d\n", n );
memcpy( thBuf+thWrite, buf, n );
thWrite+=n;
if ( thWrite==WSIZE ) {
if ( thWrite>=WSIZE ) {
for ( i=0; i<(int)out.count(); i++ )
out.at(i)->process( thBuf, WSIZE );
out.at(i)->process( thBuf, thWrite );
thWrite = 0;
}
}
else
fprintf( stderr, "DVR0: read failed : %d\n", n );
}
else
usleep(1000);
if ( waitPause>0 ) {
o = 0;
@ -917,19 +1050,11 @@ void DvbStream::recordEnded( DVBout *o, RecTimer* t, bool kill )
if ( kill ) {
removePids( o );
if ( cam )
cam->stopService( &(o->channel) );
removeOut( o );
if ( out.count()==0 )
stop();
else if ( cam ) {
for ( i=0; i<(int)out.count(); i++ ) {
if ( out.at(i)->channel.fta ) {
i=-1;
break;
}
}
if ( i!=-1 )
cam->stop();
}
}
recordingState();
if ( t )
@ -986,6 +1111,8 @@ void DvbStream::stopBroadcast()
}
for ( i=0; i<(int)p.count(); i++ ) {
removePids( p.at(i) );
if ( cam )
cam->stopService( &(p.at(i)->channel) );
removeOut( p.at(i) );
}
if ( out.count()==0 )
@ -1002,7 +1129,7 @@ int DvbStream::canStartBroadcast( bool &live, ChannelDesc *chan )
for ( i=0; i<(int)out.count(); i++ ) {
if ( (chan->tp!=out.at(i)->channel.tp) && out.at(i)->hasRec() )
return ErrIsRecording;
if ( cam && out.at(i)->hasRec() && out.at(i)->channel.fta && chan->fta && out.at(i)->channel.sid!=chan->sid )
if ( chan->fta && cam && !cam->canPlay( chan ) )
return ErrCamUsed;
if ( out.at(i)->hasLive() && chan->tp!=out.at(i)->channel.tp )
live = true;
@ -1070,6 +1197,8 @@ bool DvbStream::startBroadcast( QPtrList<ChannelDesc> *list, Ts2Rtp *rtp )
else {
broadcastList.append( new ChannelDesc( *list->at(i) ) );
no++;
if ( list->at(i)->fta && cam )
cam->startService( list->at(i) );
}
}
}
@ -1102,15 +1231,11 @@ int DvbStream::canStartTimer( bool &live, ChannelDesc *chan )
return ErrIsRecording;
if ( (o->channel.name==chan->name) && o->hasRec() )
return ErrIsRecording;
if ( (chan->tp==o->channel.tp) && o->hasRec() ) {
if ( chan->fta && cam && o->channel.fta )
return ErrCamUsed;
}
if ( chan->fta && cam && !cam->canPlay( chan ) )
return ErrCamUsed;
if ( o->hasLive() ) {
if ( chan->tp!=o->channel.tp )
live = true;
else if ( cam && chan->fta && o->channel.fta )
live = true;
}
}
return ret;
@ -1194,8 +1319,8 @@ bool DvbStream::startTimer( ChannelDesc *chan, QString path, int maxsize, RecTim
}
fprintf(stderr,"NOUT: %d\n", out.count() );
if ( chan->fta && cam && ( ((cam->running() && chan->sid!=cam->serviceId()) || !cam->running()) ) )
cam->restart( chan->sid );
if ( chan->fta && cam )
cam->startService( chan );
startReading();
@ -1205,7 +1330,7 @@ bool DvbStream::startTimer( ChannelDesc *chan, QString path, int maxsize, RecTim
int DvbStream::goLive( ChannelDesc *chan, const QString &pipeName )
int DvbStream::goLive( ChannelDesc *chan, const QString &pipeName, int ringBufSize )
{
int i;
bool stop=false;
@ -1216,10 +1341,8 @@ int DvbStream::goLive( ChannelDesc *chan, const QString &pipeName )
return ErrIsRecording;
if ( (chan->tp!=out.at(i)->channel.tp) && out.at(i)->hasBroadcast() )
return ErrIsBroadcasting;
if ( (chan->tp==out.at(i)->channel.tp) && (out.at(i)->hasBroadcast() || out.at(i)->hasRec())) {
if ( chan->fta && cam && cam->running() && (cam->serviceId()!=chan->sid) )
return ErrCamUsed;
}
if ( chan->fta && cam && !cam->canPlay( chan ) )
return ErrCamUsed;
if ( out.at(i)->channel.name==chan->name )
o = out.at(i);
}
@ -1259,11 +1382,11 @@ int DvbStream::goLive( ChannelDesc *chan, const QString &pipeName )
else
i = 0;
o->goLive( pipeName );
o->goLive( pipeName, ringBufSize );
fprintf(stderr,"NOUT: %d\n", out.count() );
if ( chan->fta && cam && !cam->running() )
cam->restart( chan->sid );
if ( chan->fta && cam )
cam->startService( chan );
startReading();
return i;
@ -1307,17 +1430,12 @@ void DvbStream::stopLive( ChannelDesc *chan )
}
for ( i=0; i<(int)p.count(); i++ ) {
removePids( p.at(i) );
if ( cam )
cam->stopService( &(p.at(i)->channel) );
removeOut( p.at(i) );
}
fprintf(stderr,"Live stopped\n");
if ( cam ) {
for ( i=0; i<(int)out.count(); i++ ) {
if ( out.at(i)->channel.fta )
camUsed = true;
}
}
if ( cam && !camUsed )
cam->stop();
if ( out.count()==0 && chan->tp!=currentTransponder )
stop();
}
@ -1343,8 +1461,6 @@ void DvbStream::stop()
wait();
fprintf(stderr,"dvbstream::run() terminated\n");
}
if ( cam )
cam->stop();
dvbEvents->stop();
stopFrontend();
}
@ -1381,7 +1497,6 @@ DvbStream::~DvbStream()
{
stop();
if ( cam ) {
cam->stop();
delete cam;
}
delete dvbEvents;

@ -62,10 +62,11 @@ public :
void setPlug( KaffeineDvbPlugin *p );
QStringList getSources( bool all=false );
bool canSource( ChannelDesc *chan );
int getPriority();
bool tuneDvb( ChannelDesc *chan, bool dvr=true );
void stopFrontend();
virtual void run();
int goLive( ChannelDesc *chan, const QString &pipeName );
int goLive( ChannelDesc *chan, const QString &pipeName, int ringBufSize );
void preStopLive();
void stopLive( ChannelDesc *chan );
void stop();
@ -89,8 +90,9 @@ public :
bool hasLive();
bool liveIsRecording();
int getSNR();
void probeCam();
void showCamDialog();
unsigned char thBuf[188*10];
struct pollfd pfd;
DVBevents *dvbEvents;
@ -109,6 +111,7 @@ protected:
private :
int setDiseqc( int switchPos, ChannelDesc *chan, int hiband, int &rotor, bool dvr );
void moveRotor( int switchPos, ChannelDesc *chan, int hiband, bool dvr );
void rotorCommand( int cmd, int n1=0, int n2=0, int n3=0 );
void gotoX( double azimuth );
double getAzimuth( double angle );
@ -119,7 +122,6 @@ private :
void removeOut( DVBout *o );
void recordingState();
void startReading();
void probeCam();
bool openFe();
bool closeFe();
void connectStatus( bool con );
@ -143,6 +145,7 @@ private :
QString timeShiftFileName;
DvbCam *cam;
bool camProbed;
int diseqcTwice;
KaffeineDvbPlugin *plug;
signals:

@ -2,10 +2,11 @@ noinst_LTLIBRARIES = libdvbapi.la
INCLUDES = -I$(top_srcdir)/kaffeine/src/input/dvb/lib
libdvbapi_la_SOURCES = diseqc.c \
libdvbapi_la_SOURCES = dvbaudio.c \
dvbca.c \
dvbdemux.c \
dvbfe.c \
dvbnet.c
dvbnet.c \
dvbvideo.c
CFLAGS = -g -O2 -Wall -Wshadow -Wpointer-arith -Wstrict-prototypes -fPIC

@ -0,0 +1,50 @@
/*
* libdvbnet - a DVB network support library
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/param.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/dvb/audio.h>
#include <errno.h>
#include "dvbaudio.h"
int dvbaudio_open(int adapter, int audiodeviceid)
{
char filename[PATH_MAX+1];
int fd;
sprintf(filename, "/dev/dvb/adapter%i/audio%i", adapter, audiodeviceid);
if ((fd = open(filename, O_RDWR)) < 0) {
// if that failed, try a flat /dev structure
sprintf(filename, "/dev/dvb%i.audio%i", adapter, audiodeviceid);
fd = open(filename, O_RDWR);
}
return fd;
}
int dvbaudio_set_bypass(int fd, int bypass)
{
return ioctl(fd, AUDIO_SET_BYPASS_MODE, bypass);
}

@ -0,0 +1,55 @@
/*
* libdvbnet - a DVB network support library
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LIBDVBAUDIO_H
#define LIBDVBAUDIO_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
/**
* Open a DVB audio device.
*
* @param adapter DVB adapter ID.
* @param audiodeviceid Id of audio device of that adapter to open.
* @return A unix file descriptor on success, or -1 on failure.
*/
extern int dvbaudio_open(int adapter, int audiodeviceid);
/**
* Control audio bypass - i.e. output decoded audio, or the raw bitstream (e.g. AC3).
*
* @param fd Audio device opened with dvbaudio_open().
* @param bypass 1=> enable bypass, 0=> disable.
* @return 0 on success, nonzero on failure.
*/
extern int dvbaudio_set_bypass(int fd, int bypass);
// FIXME: this is a stub library
#ifdef __cplusplus
}
#endif
#endif // LIBDVBAUDIO_H

@ -128,6 +128,12 @@ int dvbdemux_set_pes_filter(int fd, int pid,
filter.output = DMX_OUT_TS_TAP;
break;
#ifdef DMX_OUT_TSDEMUX_TAP
case DVBDEMUX_OUTPUT_TS_DEMUX:
filter.output = DMX_OUT_TSDEMUX_TAP;
break;
#endif
default:
return -EINVAL;
}
@ -201,6 +207,12 @@ int dvbdemux_set_pid_filter(int fd, int pid,
filter.output = DMX_OUT_TS_TAP;
break;
#ifdef DMX_OUT_TSDEMUX_TAP
case DVBDEMUX_OUTPUT_TS_DEMUX:
filter.output = DMX_OUT_TSDEMUX_TAP;
break;
#endif
default:
return -EINVAL;
}

@ -55,6 +55,7 @@ extern "C"
#define DVBDEMUX_OUTPUT_DECODER 0
#define DVBDEMUX_OUTPUT_DEMUX 1
#define DVBDEMUX_OUTPUT_DVR 2
#define DVBDEMUX_OUTPUT_TS_DEMUX 3
/**
* PES types.
@ -65,6 +66,7 @@ extern "C"
#define DVBDEMUX_PESTYPE_SUBTITLE 3
#define DVBDEMUX_PESTYPE_PCR 4
/**
* Open a demux device. Can be called multiple times. These let you setup a
* single filter per FD. It can can also be read() from if you use a section
@ -78,8 +80,8 @@ extern "C"
extern int dvbdemux_open_demux(int adapter, int demuxdevice, int nonblocking);
/**
* Open a DVR device. May be opened for writing once, or multiple times in readonly
* mode. It is used to either write() transport stream data to be demuxed
* Open a DVR device. May be opened for writing or reading once.
* It is used to either write() transport stream data to be demuxed
* (if input == DVBDEMUX_INPUT_DVR), or to read() a stream of demuxed data
* (if output == DVBDEMUX_OUTPUT_DVR).
*

@ -2,6 +2,7 @@
* libdvbfe - a DVB frontend library
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
*
* This library is free software; you can redistribute it and/or
@ -26,14 +27,16 @@
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <linux/dvb/frontend.h>
#include <libdvbmisc/dvbmisc.h>
#include "dvbfe.h"
#define GET_INFO_MIN_DELAY_US 100000
int verbose = 0;
static int dvbfe_spectral_inversion_to_kapi[][2] =
{
@ -128,6 +131,7 @@ static int dvbfe_dvbt_hierarchy_to_kapi[][2] =
{ -1, -1 }
};
static int lookupval(int val, int reverse, int table[][2])
{
int i =0;
@ -149,19 +153,16 @@ static int lookupval(int val, int reverse, int table[][2])
}
struct dvbfe_handle_prv {
struct dvbfe_handle {
int fd;
dvbfe_type_t type;
enum dvbfe_type type;
char *name;
struct timeval nextinfotime;
struct dvbfe_info cachedinfo;
int cachedreturnval;
};
dvbfe_handle_t dvbfe_open(int adapter, int frontend, int readonly)
struct dvbfe_handle *dvbfe_open(int adapter, int frontend, int readonly)
{
char filename[PATH_MAX+1];
struct dvbfe_handle_prv *fehandle;
struct dvbfe_handle *fehandle;
int fd;
struct dvb_frontend_info info;
@ -188,8 +189,8 @@ dvbfe_handle_t dvbfe_open(int adapter, int frontend, int readonly)
}
// setup structure
fehandle = (struct dvbfe_handle_prv*) malloc(sizeof(struct dvbfe_handle_prv));
memset(fehandle, 0, sizeof(struct dvbfe_handle_prv));
fehandle = (struct dvbfe_handle*) malloc(sizeof(struct dvbfe_handle));
memset(fehandle, 0, sizeof(struct dvbfe_handle));
fehandle->fd = fd;
switch(info.type) {
case FE_QPSK:
@ -214,99 +215,118 @@ dvbfe_handle_t dvbfe_open(int adapter, int frontend, int readonly)
return fehandle;
}
void dvbfe_close(dvbfe_handle_t _fehandle)
void dvbfe_close(struct dvbfe_handle *fehandle)
{
struct dvbfe_handle_prv *fehandle = (struct dvbfe_handle_prv*) _fehandle;
close(fehandle->fd);
free(fehandle->name);
free(fehandle);
}
int dvbfe_get_info(dvbfe_handle_t _fehandle, dvbfe_info_mask_t querymask, struct dvbfe_info *result)
extern int dvbfe_get_info(struct dvbfe_handle *fehandle,
enum dvbfe_info_mask querymask,
struct dvbfe_info *result,
enum dvbfe_info_querytype querytype,
int timeout)
{
int returnval = 0;
fe_status_t status;
struct dvb_frontend_parameters kparams;
struct dvbfe_handle_prv *fehandle = (struct dvbfe_handle_prv*) _fehandle;
struct timeval curtime;
// limit how often this is called to reduce bus traffic
gettimeofday(&curtime, NULL);
if ((curtime.tv_sec < fehandle->nextinfotime.tv_sec) ||
((curtime.tv_sec == fehandle->nextinfotime.tv_sec) && (curtime.tv_usec < fehandle->nextinfotime.tv_usec))) {
memcpy(result, &fehandle->cachedinfo, sizeof(struct dvbfe_info));
return fehandle->cachedreturnval;
}
struct dvb_frontend_event kevent;
int ok = 0;
// retrieve the requested values
memset(result, 0, sizeof(result));
result->type = fehandle->type;
result->name = fehandle->name;
if (querymask & DVBFE_INFO_LOCKSTATUS) {
if (!ioctl(fehandle->fd, FE_READ_STATUS, &status)) {
returnval |= DVBFE_INFO_LOCKSTATUS;
if (status & FE_HAS_SIGNAL)
result->signal = 1;
if (status & FE_HAS_CARRIER)
result->carrier = 1;
result->type = fehandle->type;
if (status & FE_HAS_VITERBI)
result->viterbi = 1;
switch(querytype) {
case DVBFE_INFO_QUERYTYPE_IMMEDIATE:
if (querymask & DVBFE_INFO_LOCKSTATUS) {
if (!ioctl(fehandle->fd, FE_READ_STATUS, &kevent.status)) {
returnval |= DVBFE_INFO_LOCKSTATUS;
}
}
if (querymask & DVBFE_INFO_FEPARAMS) {
if (!ioctl(fehandle->fd, FE_GET_FRONTEND, &kevent.parameters)) {
returnval |= DVBFE_INFO_FEPARAMS;
}
}
break;
if (status & FE_HAS_SYNC)
result->sync = 1;
case DVBFE_INFO_QUERYTYPE_LOCKCHANGE:
{
struct pollfd pollfd;
pollfd.fd = fehandle->fd;
pollfd.events = POLLIN | POLLERR;
ok = 1;
if (poll(&pollfd, 1, timeout) < 0)
ok = 0;
if (pollfd.revents & POLLERR)
ok = 0;
if (!(pollfd.revents & POLLIN))
ok = 0;
}
if (status & FE_HAS_LOCK)
result->lock = 1;
if (ok &&
((querymask & DVBFE_INFO_LOCKSTATUS) ||
(querymask & DVBFE_INFO_FEPARAMS))) {
if (!ioctl(fehandle->fd, FE_GET_EVENT, &kevent)) {
if (querymask & DVBFE_INFO_LOCKSTATUS)
returnval |= DVBFE_INFO_LOCKSTATUS;
if (querymask & DVBFE_INFO_FEPARAMS)
returnval |= DVBFE_INFO_FEPARAMS;
}
}
break;
}
if (querymask & DVBFE_INFO_FEPARAMS) {
if (!ioctl(fehandle->fd, FE_GET_FRONTEND, &kparams)) {
returnval |= DVBFE_INFO_FEPARAMS;
result->feparams.frequency = kparams.frequency;
result->feparams.inversion = lookupval(kparams.inversion, 1, dvbfe_spectral_inversion_to_kapi);
switch(fehandle->type) {
case FE_QPSK:
result->feparams.u.dvbs.symbol_rate = kparams.u.qpsk.symbol_rate;
result->feparams.u.dvbs.fec_inner =
lookupval(kparams.u.qpsk.fec_inner, 1, dvbfe_code_rate_to_kapi);
break;
case FE_QAM:
result->feparams.u.dvbc.symbol_rate = kparams.u.qam.symbol_rate;
result->feparams.u.dvbc.fec_inner =
lookupval(kparams.u.qam.fec_inner, 1, dvbfe_code_rate_to_kapi);
result->feparams.u.dvbc.modulation =
lookupval(kparams.u.qam.modulation, 1, dvbfe_dvbc_mod_to_kapi);
break;
if (returnval & DVBFE_INFO_LOCKSTATUS) {
result->signal = kevent.status & FE_HAS_SIGNAL ? 1 : 0;
result->carrier = kevent.status & FE_HAS_CARRIER ? 1 : 0;
result->viterbi = kevent.status & FE_HAS_VITERBI ? 1 : 0;
result->sync = kevent.status & FE_HAS_SYNC ? 1 : 0;
result->lock = kevent.status & FE_HAS_LOCK ? 1 : 0;
}
case FE_OFDM:
result->feparams.u.dvbt.bandwidth =
lookupval(kparams.u.ofdm.bandwidth, 1, dvbfe_dvbt_bandwidth_to_kapi);
result->feparams.u.dvbt.code_rate_HP =
lookupval(kparams.u.ofdm.code_rate_HP, 1, dvbfe_code_rate_to_kapi);
result->feparams.u.dvbt.code_rate_LP =
lookupval(kparams.u.ofdm.code_rate_LP, 1, dvbfe_code_rate_to_kapi);
result->feparams.u.dvbt.constellation =
lookupval(kparams.u.ofdm.constellation, 1, dvbfe_dvbt_const_to_kapi);
result->feparams.u.dvbt.transmission_mode =
lookupval(kparams.u.ofdm.transmission_mode, 1, dvbfe_dvbt_transmit_mode_to_kapi);
result->feparams.u.dvbt.guard_interval =
lookupval(kparams.u.ofdm.guard_interval, 1, dvbfe_dvbt_guard_interval_to_kapi);
result->feparams.u.dvbt.hierarchy_information =
lookupval(kparams.u.ofdm.hierarchy_information, 1, dvbfe_dvbt_hierarchy_to_kapi);
break;
if (returnval & DVBFE_INFO_FEPARAMS) {
result->feparams.frequency = kevent.parameters.frequency;
result->feparams.inversion = lookupval(kevent.parameters.inversion, 1, dvbfe_spectral_inversion_to_kapi);
switch(fehandle->type) {
case FE_QPSK:
result->feparams.u.dvbs.symbol_rate = kevent.parameters.u.qpsk.symbol_rate;
result->feparams.u.dvbs.fec_inner =
lookupval(kevent.parameters.u.qpsk.fec_inner, 1, dvbfe_code_rate_to_kapi);
break;
case FE_ATSC:
result->feparams.u.atsc.modulation =
lookupval(kparams.u.vsb.modulation, 1, dvbfe_atsc_mod_to_kapi);
break;
}
}
case FE_QAM:
result->feparams.u.dvbc.symbol_rate = kevent.parameters.u.qam.symbol_rate;
result->feparams.u.dvbc.fec_inner =
lookupval(kevent.parameters.u.qam.fec_inner, 1, dvbfe_code_rate_to_kapi);
result->feparams.u.dvbc.modulation =
lookupval(kevent.parameters.u.qam.modulation, 1, dvbfe_dvbc_mod_to_kapi);
break;
case FE_OFDM:
result->feparams.u.dvbt.bandwidth =
lookupval(kevent.parameters.u.ofdm.bandwidth, 1, dvbfe_dvbt_bandwidth_to_kapi);
result->feparams.u.dvbt.code_rate_HP =
lookupval(kevent.parameters.u.ofdm.code_rate_HP, 1, dvbfe_code_rate_to_kapi);
result->feparams.u.dvbt.code_rate_LP =
lookupval(kevent.parameters.u.ofdm.code_rate_LP, 1, dvbfe_code_rate_to_kapi);
result->feparams.u.dvbt.constellation =
lookupval(kevent.parameters.u.ofdm.constellation, 1, dvbfe_dvbt_const_to_kapi);
result->feparams.u.dvbt.transmission_mode =
lookupval(kevent.parameters.u.ofdm.transmission_mode, 1, dvbfe_dvbt_transmit_mode_to_kapi);
result->feparams.u.dvbt.guard_interval =
lookupval(kevent.parameters.u.ofdm.guard_interval, 1, dvbfe_dvbt_guard_interval_to_kapi);
result->feparams.u.dvbt.hierarchy_information =
lookupval(kevent.parameters.u.ofdm.hierarchy_information, 1, dvbfe_dvbt_hierarchy_to_kapi);
break;
case FE_ATSC:
result->feparams.u.atsc.modulation =
lookupval(kevent.parameters.u.vsb.modulation, 1, dvbfe_atsc_mod_to_kapi);
break;
}
}
if (querymask & DVBFE_INFO_BER) {
if (!ioctl(fehandle->fd, FE_READ_BER, &result->ber))
returnval |= DVBFE_INFO_BER;
@ -324,24 +344,15 @@ int dvbfe_get_info(dvbfe_handle_t _fehandle, dvbfe_info_mask_t querymask, struct
returnval |= DVBFE_INFO_UNCORRECTED_BLOCKS;
}
// setup for next poll
gettimeofday(&fehandle->nextinfotime, NULL);
fehandle->nextinfotime.tv_usec += GET_INFO_MIN_DELAY_US;
if (fehandle->nextinfotime.tv_usec >= 1000000) {
fehandle->nextinfotime.tv_usec -= 1000000;
fehandle->nextinfotime.tv_sec++;
}
memcpy(&fehandle->cachedinfo, result, sizeof(struct dvbfe_info));
fehandle->cachedreturnval = returnval;
// done
return returnval;
}
int dvbfe_set(dvbfe_handle_t _fehandle, struct dvbfe_parameters *params, int timeout)
int dvbfe_set(struct dvbfe_handle *fehandle,
struct dvbfe_parameters *params,
int timeout)
{
struct dvb_frontend_parameters kparams;
struct dvbfe_handle_prv *fehandle = (struct dvbfe_handle_prv*) _fehandle;
int res;
struct timeval endtime;
fe_status_t status;
@ -428,320 +439,123 @@ int dvbfe_set(dvbfe_handle_t _fehandle, struct dvbfe_parameters *params, int tim
return -ETIMEDOUT;
}
void dvbfe_poll(dvbfe_handle_t fehandle)
int dvbfe_get_pollfd(struct dvbfe_handle *handle)
{
// no implementation required yet
return handle->fd;
}
int dvbfe_set_22k_tone(struct dvbfe_handle *fehandle, enum dvbfe_sec_tone_mode tone)
{
int ret = 0;
switch (tone) {
case DVBFE_SEC_TONE_OFF:
ret = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_OFF);
break;
case DVBFE_SEC_TONE_ON:
ret = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_ON);
break;
default:
print(verbose, ERROR, 1, "Invalid command !");
break;
}
if (ret == -1)
print(verbose, ERROR, 1, "IOCTL failed !");
return ret;
}
int dvbfe_diseqc_command(dvbfe_handle_t _fehandle, char *command)
int dvbfe_set_tone_data_burst(struct dvbfe_handle *fehandle, enum dvbfe_sec_mini_cmd minicmd)
{
int i = 0;
int waittime;
int status;
struct dvb_diseqc_master_cmd master_cmd;
unsigned int tmpcmd[6];
struct dvbfe_handle_prv *fehandle = (struct dvbfe_handle_prv*) _fehandle;
char value_s[20];
int value_i;
int addr;
while(command[i]) {
/* kill whitespace */
if (isspace(command[i])) {
i++;
continue;
}
int ret = 0;
switch(command[i]) {
case 't':
if ((status = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_OFF)) != 0)
return status;
break;
case 'T':
if ((status = ioctl(fehandle->fd, FE_SET_TONE, SEC_TONE_ON)) != 0)
return status;
break;
case '_':
if ((status = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF)) != 0)
return status;
break;
switch (minicmd) {
case DVBFE_SEC_MINI_A:
ret = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_A);
break;
case DVBFE_SEC_MINI_B:
ret = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_B);
break;
default:
print(verbose, ERROR, 1, "Invalid command");
break;
}
if (ret == -1)
print(verbose, ERROR, 1, "IOCTL failed");
case 'v':
if ((status = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13)) != 0)
return status;
break;
return ret;
}
case 'V':
if ((status = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18)) != 0)
return status;
break;
int dvbfe_set_voltage(struct dvbfe_handle *fehandle, enum dvbfe_sec_voltage voltage)
{
int ret = 0;
case 'A':
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_A)) != 0)
return status;
break;
switch (voltage) {
case DVBFE_SEC_VOLTAGE_OFF:
ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF);
break;
case DVBFE_SEC_VOLTAGE_13:
ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13);
break;
case DVBFE_SEC_VOLTAGE_18:
ret = ioctl(fehandle->fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18);
break;
default:
print(verbose, ERROR, 1, "Invalid command");
break;
}
if (ret == -1)
print(verbose, ERROR, 1, "IOCTL failed");
case 'B':
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_BURST, SEC_MINI_B)) != 0)
return status;
break;
return ret;
}
case '+':
ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 1);
/* don't care if this one is not supported */
break;
int dvbfe_set_high_lnb_voltage(struct dvbfe_handle *fehandle, int on)
{
switch (on) {
case 0:
ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 0);
break;
default:
ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 1);
break;
}
return 0;
}
case '-':
ioctl(fehandle->fd, FE_ENABLE_HIGH_LNB_VOLTAGE, 0);
/* don't care if this one is not supported */
break;
int dvbfe_do_dishnetworks_legacy_command(struct dvbfe_handle *fehandle, unsigned int cmd)
{
int ret = 0;
case 'W':
waittime = atoi(command + i + 1);
if (waittime == 0) {
return -EINVAL;
}
usleep(waittime * 1000);
while(command[i] && !isspace(command[i]))
i++;
break;
ret = ioctl(fehandle->fd, FE_DISHNETWORK_SEND_LEGACY_CMD, cmd);
if (ret == -1)
print(verbose, ERROR, 1, "IOCTL failed");
case '.': // extended command
{
i++;
if (!strncmp(command+i, "D(", 2)) {
i += 2;
master_cmd.msg_len =
sscanf(command+i, "%x %x %x %x %x %x",
tmpcmd, tmpcmd+1, tmpcmd+2, tmpcmd+3, tmpcmd+4, tmpcmd+5);
if (master_cmd.msg_len == 0)
return -EINVAL;
master_cmd.msg[0] = tmpcmd[0];
master_cmd.msg[1] = tmpcmd[1];
master_cmd.msg[2] = tmpcmd[2];
master_cmd.msg[3] = tmpcmd[3];
master_cmd.msg[4] = tmpcmd[4];
master_cmd.msg[5] = tmpcmd[5];
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if (!strncmp(command+i, "Dband(", 6)) {
if (sscanf(command+i+6, "%i %2s", &addr, value_s) != 2)
return -EINVAL;
if (!strncmp(value_s, "lo", 2)) {
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x20;
master_cmd.msg_len = 3;
} else if (!strncmp(value_s, "hi", 2)) {
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x24;
master_cmd.msg_len = 3;
} else {
return -EINVAL;
}
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if ((!strncmp(command+i, "Dpolarisation(", 14) ||
(!strncmp(command+i, "Dpolarization(", 14)))) {
if (sscanf(command+i+14, "%i %1s", &addr, value_s) != 2)
return -EINVAL;
switch(*value_s) {
case 'H':
case 'L':
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x25;
master_cmd.msg_len = 3;
break;
case 'V':
case 'R':
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x21;
master_cmd.msg_len = 3;
break;
default:
return -EINVAL;
}
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if (!strncmp(command+i, "Dsatellite_position(", 20)) {
if (sscanf(command+i+20, "%i %1s", &addr, value_s) != 2)
return -EINVAL;
switch(*value_s) {
case 'A':
case 'C':
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x22;
master_cmd.msg_len = 3;
break;
case 'B':
case 'D':
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x26;
master_cmd.msg_len = 3;
break;
default:
return -EINVAL;
}
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if (!strncmp(command+i, "Dswitch_option(", 15)) {
if (sscanf(command+i+15, "%i %1s", &addr, value_s) != 2)
return -EINVAL;
switch(*value_s) {
case 'A':
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x23;
master_cmd.msg_len = 3;
break;
case 'B':
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x27;
master_cmd.msg_len = 3;
break;
default:
return -EINVAL;
}
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if (!strncmp(command+i, "Dport_pins(", 11)) {
int mask;
if (sscanf(command+i+11, "%i %i %i", &addr, &mask, &value_i) != 3)
return -EINVAL;
if (mask & 0x0f) {
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x38;
master_cmd.msg[3] = ((mask & 0x0f) << 4) | (value_i & 0x0f);
master_cmd.msg_len = 4;
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
}
if (mask & 0xf0) {
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x39;
master_cmd.msg[3] = (mask & 0xf0) | ((value_i & 0xf0) >> 4);
master_cmd.msg_len = 4;
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
}
} else if (!strncmp(command+i, "Dgoto_preset(", 13)) {
if (sscanf(command+i+13, "%i %i", &addr, &value_i) != 2)
return -EINVAL;
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x3b;
master_cmd.msg[3] = value_i;
master_cmd.msg_len = 4;
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if (!strncmp(command+i, "Dgoto_angle(", 12)) {
int integer = 0;
int fraction = 0;
char *tmp;
if (sscanf(command+i+12, "%i %s", &addr, value_s) != 2)
return -EINVAL;
// parse the integer and fractional parts using fixed point
integer = atoi(value_s);
tmp = strchr(value_s, '.');
if (tmp != NULL) {
tmp++;
tmp[3] = 0;
fraction = ((atoi(tmp) * 16000) / 1000000) & 0xf;
}
// generate the command
master_cmd.msg[0] = 0xe0;
master_cmd.msg[1] = addr;
master_cmd.msg[2] = 0x6e;
if (integer < -256) {
return -EINVAL;
} else if (integer < 0) {
integer = -integer;
master_cmd.msg[3] = 0xf0;
} else if (integer < 256) {
master_cmd.msg[3] = 0x00;
} else if (integer < 512) {
integer -= 256;
master_cmd.msg[3] = 0x10;
} else {
return -EINVAL;
}
master_cmd.msg[3] |= ((integer / 16) & 0x0f);
integer = integer % 16;
master_cmd.msg[4] |= ((integer & 0x0f) << 4) | fraction;
master_cmd.msg_len = 5;
if ((status = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &master_cmd)) != 0)
return status;
} else if (!strncmp(command+i, "dishnetworks(", 13)) {
if (sscanf(command+i+13, "%i", tmpcmd) != 1)
return -EINVAL;
if ((status = ioctl(fehandle->fd, FE_DISHNETWORK_SEND_LEGACY_CMD, tmpcmd)) != 0)
return status;
}
return ret;
}
/* skip to the end... */
while(command[i] && (command[i] != ')'))
i++;
break;
}
int dvbfe_do_diseqc_command(struct dvbfe_handle *fehandle, uint8_t *data, uint8_t len)
{
int ret = 0;
struct dvb_diseqc_master_cmd diseqc_message;
if (len > 6)
return -EINVAL;
default:
return -EINVAL;
}
diseqc_message.msg_len = len;
memcpy(diseqc_message.msg, data, len);
i++;
}
ret = ioctl(fehandle->fd, FE_DISEQC_SEND_MASTER_CMD, &diseqc_message);
if (ret == -1)
print(verbose, ERROR, 1, "IOCTL failed");
return 0;
return ret;
}
int dvbfe_diseqc_read(dvbfe_handle_t _fehandle, int timeout, unsigned char *buf, unsigned int len)
int dvbfe_diseqc_read(struct dvbfe_handle *fehandle, int timeout, unsigned char *buf, unsigned int len)
{
struct dvb_diseqc_slave_reply reply;
int result;
struct dvbfe_handle_prv *fehandle = (struct dvbfe_handle_prv*) _fehandle;
if (len > 4)
len = 4;

@ -2,6 +2,7 @@
* libdvbfe - a DVB frontend library
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
*
* This library is free software; you can redistribute it and/or
@ -32,27 +33,20 @@ extern "C"
/**
* The types of frontend we support.
*/
typedef enum dvbfe_type {
enum dvbfe_type {
DVBFE_TYPE_DVBS,
DVBFE_TYPE_DVBC,
DVBFE_TYPE_DVBT,
DVBFE_TYPE_ATSC,
} dvbfe_type_t;
typedef enum dvbfe_polarization {
DVBFE_POLARIZATION_H,
DVBFE_POLARIZATION_V,
DVBFE_POLARIZATION_L,
DVBFE_POLARIZATION_R,
} dvbfe_polarization_t;
};
typedef enum dvbfe_spectral_inversion {
enum dvbfe_spectral_inversion {
DVBFE_INVERSION_OFF,
DVBFE_INVERSION_ON,
DVBFE_INVERSION_AUTO
} dvbfe_spectral_inversion_t;
};
typedef enum dvbfe_code_rate {
enum dvbfe_code_rate {
DVBFE_FEC_NONE,
DVBFE_FEC_1_2,
DVBFE_FEC_2_3,
@ -63,9 +57,9 @@ typedef enum dvbfe_code_rate {
DVBFE_FEC_7_8,
DVBFE_FEC_8_9,
DVBFE_FEC_AUTO
} dvbfe_code_rate_t;
};
typedef enum dvbfe_dvbt_const {
enum dvbfe_dvbt_const {
DVBFE_DVBT_CONST_QPSK,
DVBFE_DVBT_CONST_QAM_16,
DVBFE_DVBT_CONST_QAM_32,
@ -73,106 +67,121 @@ typedef enum dvbfe_dvbt_const {
DVBFE_DVBT_CONST_QAM_128,
DVBFE_DVBT_CONST_QAM_256,
DVBFE_DVBT_CONST_AUTO
} dvbfe_dvbt_const_t;
};
typedef enum dvbfe_dvbc_mod {
enum dvbfe_dvbc_mod {
DVBFE_DVBC_MOD_QAM_16,
DVBFE_DVBC_MOD_QAM_32,
DVBFE_DVBC_MOD_QAM_64,
DVBFE_DVBC_MOD_QAM_128,
DVBFE_DVBC_MOD_QAM_256,
DVBFE_DVBC_MOD_AUTO,
} dvbfe_dvbc_mod_t;
};
typedef enum dvbfe_atsc_mod {
enum dvbfe_atsc_mod {
DVBFE_ATSC_MOD_QAM_64,
DVBFE_ATSC_MOD_QAM_256,
DVBFE_ATSC_MOD_VSB_8,
DVBFE_ATSC_MOD_VSB_16,
DVBFE_ATSC_MOD_AUTO
} dvbfe_atsc_mod_t;
};
typedef enum dvbfe_dvbt_transmit_mode {
enum dvbfe_dvbt_transmit_mode {
DVBFE_DVBT_TRANSMISSION_MODE_2K,
DVBFE_DVBT_TRANSMISSION_MODE_8K,
DVBFE_DVBT_TRANSMISSION_MODE_AUTO
} dvbfe_dvbt_transmit_mode_t;
};
typedef enum dvbfe_dvbt_bandwidth {
enum dvbfe_dvbt_bandwidth {
DVBFE_DVBT_BANDWIDTH_8_MHZ,
DVBFE_DVBT_BANDWIDTH_7_MHZ,
DVBFE_DVBT_BANDWIDTH_6_MHZ,
DVBFE_DVBT_BANDWIDTH_AUTO
} dvbfe_dvbt_bandwidth_t;
};
typedef enum dvbfe_dvbt_guard_interval {
enum dvbfe_dvbt_guard_interval {
DVBFE_DVBT_GUARD_INTERVAL_1_32,
DVBFE_DVBT_GUARD_INTERVAL_1_16,
DVBFE_DVBT_GUARD_INTERVAL_1_8,
DVBFE_DVBT_GUARD_INTERVAL_1_4,
DVBFE_DVBT_GUARD_INTERVAL_AUTO
} dvbfe_dvbt_guard_interval_t;
};
typedef enum dvbfe_dvbt_hierarchy {
enum dvbfe_dvbt_hierarchy {
DVBFE_DVBT_HIERARCHY_NONE,
DVBFE_DVBT_HIERARCHY_1,
DVBFE_DVBT_HIERARCHY_2,
DVBFE_DVBT_HIERARCHY_4,
DVBFE_DVBT_HIERARCHY_AUTO
} dvbfe_dvbt_hierarchy_t;
};
/**
* Structure used to store and communicate frontend parameters.
*/
struct dvbfe_parameters {
uint32_t frequency;
dvbfe_spectral_inversion_t inversion;
enum dvbfe_spectral_inversion inversion;
union {
struct {
uint32_t symbol_rate;
dvbfe_code_rate_t fec_inner;
dvbfe_polarization_t polarization;
enum dvbfe_code_rate fec_inner;
} dvbs;
struct {
uint32_t symbol_rate;
dvbfe_code_rate_t fec_inner;
dvbfe_dvbc_mod_t modulation;
enum dvbfe_code_rate fec_inner;
enum dvbfe_dvbc_mod modulation;
} dvbc;
struct {
dvbfe_dvbt_bandwidth_t bandwidth;
dvbfe_code_rate_t code_rate_HP;
dvbfe_code_rate_t code_rate_LP;
dvbfe_dvbt_const_t constellation;
dvbfe_dvbt_transmit_mode_t transmission_mode;
dvbfe_dvbt_guard_interval_t guard_interval;
dvbfe_dvbt_hierarchy_t hierarchy_information;
enum dvbfe_dvbt_bandwidth bandwidth;
enum dvbfe_code_rate code_rate_HP;
enum dvbfe_code_rate code_rate_LP;
enum dvbfe_dvbt_const constellation;
enum dvbfe_dvbt_transmit_mode transmission_mode;
enum dvbfe_dvbt_guard_interval guard_interval;
enum dvbfe_dvbt_hierarchy hierarchy_information;
} dvbt;
struct {
dvbfe_atsc_mod_t modulation;
enum dvbfe_atsc_mod modulation;
} atsc;
} u;
};
enum dvbfe_sec_voltage {
DVBFE_SEC_VOLTAGE_13,
DVBFE_SEC_VOLTAGE_18,
DVBFE_SEC_VOLTAGE_OFF
};
enum dvbfe_sec_tone_mode {
DVBFE_SEC_TONE_ON,
DVBFE_SEC_TONE_OFF
};
enum dvbfe_sec_mini_cmd {
DVBFE_SEC_MINI_A,
DVBFE_SEC_MINI_B
};
/**
* Mask of values used in the dvbfe_get_info() call.
*/
typedef enum dvbfe_info_mask {
enum dvbfe_info_mask {
DVBFE_INFO_LOCKSTATUS = 0x01,
DVBFE_INFO_FEPARAMS = 0x02,
DVBFE_INFO_BER = 0x04,
DVBFE_INFO_SIGNAL_STRENGTH = 0x08,
DVBFE_INFO_SNR = 0x10,
DVBFE_INFO_UNCORRECTED_BLOCKS = 0x20,
} dvbfe_info_mask_t;
};
/**
* Structure containing values used by the dvbfe_get_info() call.
*/
struct dvbfe_info {
dvbfe_type_t type; /* always retrieved */
enum dvbfe_type type; /* always retrieved */
const char *name; /* always retrieved */
unsigned int signal : 1; /* } DVBFE_INFO_LOCKSTATUS */
unsigned int carrier : 1; /* } */
@ -186,10 +195,24 @@ struct dvbfe_info {
uint32_t ucblocks; /* DVBFE_INFO_UNCORRECTED_BLOCKS */
};
/**
* Possible types of query used in dvbfe_get_info.
*
* DVBFE_INFO_QUERYTYPE_IMMEDIATE - interrogate frontend for most up to date values.
* DVBFE_INFO_QUERYTYPE_LOCKCHANGE - return details from queued lock status
* change events, or wait for one to occur
* if none are queued.
*/
enum dvbfe_info_querytype {
DVBFE_INFO_QUERYTYPE_IMMEDIATE,
DVBFE_INFO_QUERYTYPE_LOCKCHANGE,
};
/**
* Frontend handle datatype.
*/
typedef void *dvbfe_handle_t;
struct dvbfe_handle;
/**
* Open a DVB frontend.
@ -199,18 +222,21 @@ typedef void *dvbfe_handle_t;
* @param readonly If 1, frontend will be opened in readonly mode only.
* @return A handle on success, or NULL on failure.
*/
extern dvbfe_handle_t dvbfe_open(int adapter, int frontend, int readonly);
extern struct dvbfe_handle *dvbfe_open(int adapter, int frontend, int readonly);
/**
* Close a DVB frontend.
*
* @param fehandle Handle opened with dvbfe_open().
*/
extern void dvbfe_close(dvbfe_handle_t handle);
extern void dvbfe_close(struct dvbfe_handle *handle);
/**
* Set the frontend tuning parameters.
*
* Note: this function provides only the basic tuning operation; you might want to
* investigate dvbfe_set_sec() in sec.h for a unified device tuning operation.
*
* @param fehandle Handle opened with dvbfe_open().
* @param params Params to set.
* @param timeout <0 => wait forever for lock. 0=>return immediately, >0=>
@ -218,14 +244,9 @@ extern void dvbfe_close(dvbfe_handle_t handle);
* @return 0 on locked (or if timeout==0 and everything else worked), or
* nonzero on failure (including no lock).
*/
extern int dvbfe_set(dvbfe_handle_t fehandle, struct dvbfe_parameters *params, int timeout);
/**
* Call this function regularly from a loop to maintain the frontend lock.
*
* @param fehandle Handle opened with dvbfe_open().
*/
extern void dvbfe_poll(dvbfe_handle_t fehandle);
extern int dvbfe_set(struct dvbfe_handle *fehandle,
struct dvbfe_parameters *params,
int timeout);
/**
* Retrieve information about the frontend.
@ -233,62 +254,66 @@ extern void dvbfe_poll(dvbfe_handle_t fehandle);
* @param fehandle Handle opened with dvbfe_open().
* @param querymask ORed bitmask of desired DVBFE_INFO_* values.
* @param result Where to put the retrieved results.
* @param querytype Type of query requested.
* @param timeout Timeout in ms to use if querytype==lockchange (0=>no timeout, <0=> wait forever).
* @return ORed bitmask of DVBFE_INFO_* indicating which values were read successfully.
*/
extern int dvbfe_get_info(dvbfe_handle_t fehandle, dvbfe_info_mask_t querymask, struct dvbfe_info *result);
extern int dvbfe_get_info(struct dvbfe_handle *fehandle,
enum dvbfe_info_mask querymask,
struct dvbfe_info *result,
enum dvbfe_info_querytype querytype,
int timeout);
/**
* Execute a DISEQC command string.
*
* A diseqc command consists of a sequence of the following codes, separated by
* whitespace:
* Simple commands:
* t - turn 22kHz tone off.
* T - turn 22kHz tone on.
* _ - set voltage to 0v (i.e. off).
* v - set voltage to 13v.
* V - set voltage to 18v.
* + - Enable high LNB voltage.
* - - Disable high LNB voltage.
* A - send DISEQC mini command A.
* B - send DISEQC mini command B.
* Wii - Delay for ii milliseconds.
*
* Extended commands:
* .dishnetworks(<value>) - Send a dish networks legacy command <value>
* .D(<value> ...) - Send a raw diseqc master command. The command may be up
* to 6 bytes long.
* .Dband(<addr> <lo|hi>) - Set frequency band hi or lo.
* .Dpolarisation(<addr> <V|H|L|R>) - Set polarisation.
* .Dsatellite_position(<addr> <A|B>) - Set "satellite position" input switch.
* .Dswitch_option(<addr> <A|B>) - Set "switch option" input switch.
* .Dport_pins(<addr> <mask> <value>) - Set all input switches. Mask and value
* are hex-ascii 8 bit bytes. Only bits with a corresponding '1' in mask
* will be changed.
* .Dgoto_preset(<addr> <index>) - Set a positioner to a preset index (integer)
* .Dgoto_angle(<addr> <angle>) - Set a positioner to a given angle
* (e.g. 49.6). The angle may range between -180 to 496. It may include a
* fractional part.
*
* All integer values use standard notation - no prefix=>decimal, 0x=>hex etc.
*
* Set <addr> to 0 if you just have a simple DISEQC setup (e.g. one switch). See
* the DISEQC specification at http://www.eutelsat.org/ for full information.
*
* Comments begin with '#' - any characters after this will be ignored
* to the end of the line.
*
* Examples:
* S-19.2E 11700000 V 9750000 t v W15 .D(E0 10 38 F0) W15 A W15 t
* S-19.2E 99999999 V 10600000 t v W15 .D(E0 10 38 F1) W15 A W15 T
* S-19.2E 11700000 H 9750000 t V W15 .D(E0 10 38 F2) W15 A W15 t
* S-19.2E 99999999 H 10600000 t V W15 .D(E0 10 38 F3) W15 A W15 T
* Get a file descriptor for polling for lock status changes.
*
* @param fehandle Handle opened with dvbfe_open().
* @param command Command to execute.
* @return 0 on success, nonzero on failure.
* @return FD for polling.
*/
extern int dvbfe_get_pollfd(struct dvbfe_handle *handle);
/**
* Tone/Data Burst control
* @param fehandle Handle opened with dvbfe_open().
* @param tone, SEC_TONE_ON/SEC_TONE_OFF
*/
extern int dvbfe_set_22k_tone(struct dvbfe_handle *handle, enum dvbfe_sec_tone_mode tone);
/**
* 22khz Tone control
* @param fehandle Handle opened with dvbfe_open().
* @param adapter, minicmd, SEC_MINI_A/SEC_MINI_B
*/
extern int dvbfe_set_tone_data_burst(struct dvbfe_handle *handle, enum dvbfe_sec_mini_cmd minicmd);
/**
* Voltage control
* @param fehandle Handle opened with dvbfe_open().
* @param polarization, SEC_VOLTAGE_13/SEC_VOLTAGE_18/SEC_VOLTAGE_OFF
*/
extern int dvbfe_set_voltage(struct dvbfe_handle *handle, enum dvbfe_sec_voltage voltage);
/**
* High LNB voltage control (increases voltage by 1v to compensate for long cables)
* @param fehandle Handle opened with dvbfe_open().
* @param on 1 to enable, 0 to disable.
*/
extern int dvbfe_set_high_lnb_voltage(struct dvbfe_handle *fehandle, int on);
/**
* Send a legacy Dish Networks command
* @param fehandle Handle opened with dvbfe_open().
* @param cmd, the command to send
*/
extern int dvbfe_do_dishnetworks_legacy_command(struct dvbfe_handle *handle, unsigned int cmd);
/**
* Send a DiSEqC Command
* @param fehandle Handle opened with dvbfe_open().
* @param data, a pointer to am array containing the data to be sent.
* @param len Length of data in bytes, max 6 bytes.
*/
extern int dvbfe_diseqc_command(dvbfe_handle_t fehandle, char *command);
extern int dvbfe_do_diseqc_command(struct dvbfe_handle *handle, uint8_t *data, uint8_t len);
/**
* Read a DISEQC response from the frontend.
@ -299,7 +324,7 @@ extern int dvbfe_diseqc_command(dvbfe_handle_t fehandle, char *command);
* @param len Number of bytes in buffer.
* @return >= 0 on success (number of received bytes), <0 on failure.
*/
extern int dvbfe_diseqc_read(dvbfe_handle_t fehandle, int timeout, unsigned char *buf, unsigned int len);
extern int dvbfe_diseqc_read(struct dvbfe_handle *fehandle, int timeout, unsigned char *buf, unsigned int len);
#ifdef __cplusplus
}

@ -44,9 +44,10 @@ int dvbnet_open(int adapter, int netdeviceid)
return fd;
}
int dvbnet_add_interface(int fd, uint16_t pid, int encapsulation)
int dvbnet_add_interface(int fd, uint16_t pid, enum dvbnet_encap encapsulation)
{
struct dvb_net_if params;
int status;
memset(&params, 0, sizeof(params));
params.pid = pid;
@ -63,10 +64,14 @@ int dvbnet_add_interface(int fd, uint16_t pid, int encapsulation)
default:
return -EINVAL;
}
return ioctl(fd, NET_ADD_IF, &params);
status = ioctl(fd, NET_ADD_IF, &params);
if (status < 0)
return status;
return params.if_num;
}
int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, int *encapsulation)
int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, enum dvbnet_encap *encapsulation)
{
struct dvb_net_if info;
int res;

@ -31,10 +31,10 @@ extern "C"
/**
* Possible encapsulations of data.
*/
typedef enum dvbnet_encap {
enum dvbnet_encap {
DVBNET_ENCAP_MPE,
DVBNET_ENCAP_ULE,
} dvbnet_encap_t;
};
/**
* The maximum allowed number of dvb network devices per adapter netdevice.
@ -56,9 +56,9 @@ extern int dvbnet_open(int adapter, int netdeviceid);
* @param fd FD opened with libdvbnet_open().
* @param pid PID of the stream containing the network data.
* @param encapsulation Encapsulation type of the stream (one of DVBNET_ENCAP_*).
* @return 0 on success, nonzero on failure.
* @return Index of new interface on success, < 0 on failure.
*/
extern int dvbnet_add_interface(int fd, uint16_t pid, int encapsulation);
extern int dvbnet_add_interface(int fd, uint16_t pid, enum dvbnet_encap encapsulation);
/**
* Get details of a DVBNET interface.
@ -69,7 +69,7 @@ extern int dvbnet_add_interface(int fd, uint16_t pid, int encapsulation);
* @param encapsulation The encapsulation of the interface (DVBNET_ENCAP_*).
* @return 0 on success, nonzero on failure.
*/
extern int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, int *encapsulation);
extern int dvbnet_get_interface(int fd, int ifnum, uint16_t *pid, enum dvbnet_encap *encapsulation);
/**
* Remove a DVBNET interface.

@ -0,0 +1,46 @@
/*
* libdvbnet - a DVB network support library
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/param.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/dvb/video.h>
#include <errno.h>
#include "dvbvideo.h"
int dvbvideo_open(int adapter, int videodeviceid)
{
char filename[PATH_MAX+1];
int fd;
sprintf(filename, "/dev/dvb/adapter%i/video%i", adapter, videodeviceid);
if ((fd = open(filename, O_RDWR)) < 0) {
// if that failed, try a flat /dev structure
sprintf(filename, "/dev/dvb%i.video%i", adapter, videodeviceid);
fd = open(filename, O_RDWR);
}
return fd;
}

@ -0,0 +1,46 @@
/*
* libdvbnet - a DVB network support library
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LIBDVBVIDEO_H
#define LIBDVBVIDEO_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
/**
* Open a DVB video device.
*
* @param adapter DVB adapter ID.
* @param videodeviceid Id of video device of that adapter to open.
* @return A unix file descriptor on success, or -1 on failure.
*/
extern int dvbvideo_open(int adapter, int videodeviceid);
// FIXME: this is a stub library
#ifdef __cplusplus
}
#endif
#endif // LIBDVBVIDEO_H

@ -16,6 +16,9 @@ libdvben50221_la_SOURCES = asn_1.c \
en50221_app_teletext.c \
en50221_app_utils.c \
en50221_session.c \
en50221_transport.c
en50221_transport.c \
en50221_stdcam.c \
en50221_stdcam_llci.c \
en50221_stdcam_hlci.c
CFLAGS = -g -O2 -DLOG_LEVEL=1 -Wall -Wshadow -Wpointer-arith -Wstrict-prototypes -fPIC

@ -2,8 +2,8 @@
ASN.1 routines, implementation for libdvben50221
an implementation for the High Level Common Interface
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
@ -17,65 +17,67 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include "asn_1.h"
int asn_1_decode(uint16_t *length, uint8_t *asn_1_array, uint32_t asn_1_array_len)
int asn_1_decode(uint16_t * length, uint8_t * asn_1_array,
uint32_t asn_1_array_len)
{
uint8_t length_field;
if (asn_1_array_len < 1)
return -1;
if (asn_1_array_len < 1)
return -1;
length_field = asn_1_array[0];
if (length_field < 0x80) {
if (length_field < 0x80) {
// there is only one word
*length = length_field & 0x7f;
return 1;
} else if (length_field == 0x81) {
if (asn_1_array_len < 2)
return -1;
*length = asn_1_array[1];
return 2;
} else if (length_field == 0x82) {
if (asn_1_array_len < 3)
return -1;
*length = (asn_1_array[1] << 8) | asn_1_array[2];
return 3;
}
return -1;
return 1;
} else if (length_field == 0x81) {
if (asn_1_array_len < 2)
return -1;
*length = asn_1_array[1];
return 2;
} else if (length_field == 0x82) {
if (asn_1_array_len < 3)
return -1;
*length = (asn_1_array[1] << 8) | asn_1_array[2];
return 3;
}
return -1;
}
int asn_1_encode(uint16_t length, uint8_t *asn_1_array, uint32_t asn_1_array_len)
int asn_1_encode(uint16_t length, uint8_t * asn_1_array,
uint32_t asn_1_array_len)
{
if (length < 0x80) {
if (asn_1_array_len < 1)
return -1;
if (length < 0x80) {
if (asn_1_array_len < 1)
return -1;
asn_1_array[0] = length & 0x7f;
return 1;
asn_1_array[0] = length & 0x7f;
return 1;
} else if (length < 0x100) {
if (asn_1_array_len < 2)
return -1;
asn_1_array[0] = 0x81;
asn_1_array[1] = length;
return 2;
} else {
if (asn_1_array_len < 3)
return -1;
asn_1_array[0] = 0x82;
asn_1_array[1] = length >> 8;
asn_1_array[2] = length;
return 3;
if (asn_1_array_len < 2)
return -1;
asn_1_array[0] = 0x81;
asn_1_array[1] = length;
return 2;
} else {
if (asn_1_array_len < 3)
return -1;
asn_1_array[0] = 0x82;
asn_1_array[1] = length >> 8;
asn_1_array[2] = length;
return 3;
}
// never reached
// never reached
}

@ -2,8 +2,8 @@
ASN.1 routines, implementation for libdvben50221
an implementation for the High Level Common Interface
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
@ -17,25 +17,25 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASN_1_H__
#define __ASN_1_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
int asn_1_decode(uint16_t *length, uint8_t *asn_1_array, uint32_t asn_1_array_len);
int asn_1_encode(uint16_t length, uint8_t *asn_1_array, uint32_t asn_1_array_len);
int asn_1_decode(uint16_t * length, uint8_t * asn_1_array,
uint32_t asn_1_array_len);
int asn_1_encode(uint16_t length, uint8_t * asn_1_array,
uint32_t asn_1_array_len);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -28,106 +28,107 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_ai_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_ai {
struct en50221_app_send_functions *funcs;
en50221_app_ai_callback callback;
void *callback_arg;
en50221_app_ai_callback callback;
void *callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_ai_parse_app_info(struct en50221_app_ai_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_ai_parse_app_info(struct en50221_app_ai *ai,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_ai en50221_app_ai_create(struct en50221_app_send_functions *funcs)
struct en50221_app_ai *en50221_app_ai_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_ai_private *private = NULL;
struct en50221_app_ai *ai = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_ai_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->callback = NULL;
// create structure and set it up
ai = malloc(sizeof(struct en50221_app_ai));
if (ai == NULL) {
return NULL;
}
ai->funcs = funcs;
ai->callback = NULL;
pthread_mutex_init(&private->lock, NULL);
pthread_mutex_init(&ai->lock, NULL);
// done
return private;
// done
return ai;
}
void en50221_app_ai_destroy(en50221_app_ai ai)
void en50221_app_ai_destroy(struct en50221_app_ai *ai)
{
struct en50221_app_ai_private *private = (struct en50221_app_ai_private *) ai;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&ai->lock);
free(ai);
}
void en50221_app_ai_register_callback(en50221_app_ai ai, en50221_app_ai_callback callback, void *arg)
void en50221_app_ai_register_callback(struct en50221_app_ai *ai,
en50221_app_ai_callback callback,
void *arg)
{
struct en50221_app_ai_private *private = (struct en50221_app_ai_private *) ai;
pthread_mutex_lock(&private->lock);
private->callback = callback;
private->callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&ai->lock);
ai->callback = callback;
ai->callback_arg = arg;
pthread_mutex_unlock(&ai->lock);
}
int en50221_app_ai_enquiry(en50221_app_ai ai, uint16_t session_number)
int en50221_app_ai_enquiry(struct en50221_app_ai *ai,
uint16_t session_number)
{
struct en50221_app_ai_private *private = (struct en50221_app_ai_private *) ai;
uint8_t data[4];
uint8_t data[4];
data[0] = (TAG_APP_INFO_ENQUIRY >> 16) & 0xFF;
data[1] = (TAG_APP_INFO_ENQUIRY >> 8) & 0xFF;
data[2] = TAG_APP_INFO_ENQUIRY & 0xFF;
data[3] = 0;
data[0] = (TAG_APP_INFO_ENQUIRY >> 16) & 0xFF;
data[1] = (TAG_APP_INFO_ENQUIRY >> 8) & 0xFF;
data[2] = TAG_APP_INFO_ENQUIRY & 0xFF;
data[3] = 0;
return private->funcs->send_data(private->funcs->arg, session_number, data, 4);
return ai->funcs->send_data(ai->funcs->arg, session_number, data, 4);
}
int en50221_app_ai_entermenu(en50221_app_ai ai, uint16_t session_number)
int en50221_app_ai_entermenu(struct en50221_app_ai *ai,
uint16_t session_number)
{
struct en50221_app_ai_private *private = (struct en50221_app_ai_private *) ai;
uint8_t data[4];
uint8_t data[4];
data[0] = (TAG_ENTER_MENU >> 16) & 0xFF;
data[1] = (TAG_ENTER_MENU >> 8) & 0xFF;
data[2] = TAG_ENTER_MENU & 0xFF;
data[3] = 0;
data[0] = (TAG_ENTER_MENU >> 16) & 0xFF;
data[1] = (TAG_ENTER_MENU >> 8) & 0xFF;
data[2] = TAG_ENTER_MENU & 0xFF;
data[3] = 0;
return private->funcs->send_data(private->funcs->arg, session_number, data, 4);
return ai->funcs->send_data(ai->funcs->arg, session_number, data, 4);
}
int en50221_app_ai_message(en50221_app_ai ai,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_ai_message(struct en50221_app_ai *ai,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_ai_private *private = (struct en50221_app_ai_private *) ai;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_APP_INFO:
return en50221_app_ai_parse_app_info(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_APP_INFO:
return en50221_app_ai_parse_app_info(ai, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
@ -136,50 +137,55 @@ int en50221_app_ai_message(en50221_app_ai ai,
static int en50221_app_ai_parse_app_info(struct en50221_app_ai_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_ai_parse_app_info(struct en50221_app_ai *ai,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// parse the length field
int length_field_len;
uint16_t asn_data_length;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "Received data with invalid length from module on slot %02x\n", slot_id);
return -1;
}
// check it
if (asn_data_length < 6) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *app_info = data + length_field_len;
// parse the fields
uint8_t application_type = app_info[0];
uint16_t application_manufacturer = (app_info[1] << 8) | app_info[2];
uint16_t manufacturer_code = (app_info[3] << 8) | app_info[4];
uint8_t menu_string_length = app_info[5];
uint8_t *menu_string = app_info + 6;
// check the menu_string_length
if (menu_string_length > (asn_data_length-6)) {
print(LOG_LEVEL, ERROR, 1, "Received bad menu string length - adjusting\n");
menu_string_length = asn_data_length-6;
}
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_ai_callback cb = private->callback;
void *cb_arg = private->callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, application_type,
application_manufacturer, manufacturer_code, menu_string_length, menu_string);
}
return 0;
// parse the length field
int length_field_len;
uint16_t asn_data_length;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1,
"Received data with invalid length from module on slot %02x\n",
slot_id);
return -1;
}
// check it
if (asn_data_length < 6) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *app_info = data + length_field_len;
// parse the fields
uint8_t application_type = app_info[0];
uint16_t application_manufacturer = (app_info[1] << 8) | app_info[2];
uint16_t manufacturer_code = (app_info[3] << 8) | app_info[4];
uint8_t menu_string_length = app_info[5];
uint8_t *menu_string = app_info + 6;
// check the menu_string_length
if (menu_string_length > (asn_data_length - 6)) {
print(LOG_LEVEL, ERROR, 1,
"Received bad menu string length - adjusting\n");
menu_string_length = asn_data_length - 6;
}
// tell the app
pthread_mutex_lock(&ai->lock);
en50221_app_ai_callback cb = ai->callback;
void *cb_arg = ai->callback_arg;
pthread_mutex_unlock(&ai->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number,
application_type, application_manufacturer,
manufacturer_code, menu_string_length,
menu_string);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_AI_H__
#define __EN50221_APPLICATION_AI_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -52,15 +51,19 @@ extern "C"
* @param menu_string The menu string itself.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_ai_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t application_type, uint16_t application_manufacturer,
uint16_t manufacturer_code, uint8_t menu_string_length,
uint8_t *menu_string);
typedef int (*en50221_app_ai_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t application_type,
uint16_t application_manufacturer,
uint16_t manufacturer_code,
uint8_t menu_string_length,
uint8_t * menu_string);
/**
* Opaque type representing an application information resource.
*/
typedef void *en50221_app_ai;
struct en50221_app_ai;
/**
* Create an instance of an application information resource.
@ -68,14 +71,14 @@ typedef void *en50221_app_ai;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_ai en50221_app_ai_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_ai *en50221_app_ai_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of an application information resource.
*
* @param ai Instance to destroy.
*/
extern void en50221_app_ai_destroy(en50221_app_ai ai);
extern void en50221_app_ai_destroy(struct en50221_app_ai *ai);
/**
* Register a callback for reception of application_info objects.
@ -84,7 +87,9 @@ extern void en50221_app_ai_destroy(en50221_app_ai ai);
* @param callback Callback function.
* @param arg Private argument passed during calls to the callback.
*/
extern void en50221_app_ai_register_callback(en50221_app_ai ai, en50221_app_ai_callback, void *arg);
extern void en50221_app_ai_register_callback(struct en50221_app_ai *ai,
en50221_app_ai_callback,
void *arg);
/**
* send a enquiry for the app_info provided by a module
@ -93,7 +98,8 @@ extern void en50221_app_ai_register_callback(en50221_app_ai ai, en50221_app_ai_c
* @param session_number Session to send on.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_ai_enquiry(en50221_app_ai ai, uint16_t session_number);
extern int en50221_app_ai_enquiry(struct en50221_app_ai *ai,
uint16_t session_number);
/**
* send a enter_menu tag, this will make the application
@ -103,7 +109,8 @@ extern int en50221_app_ai_enquiry(en50221_app_ai ai, uint16_t session_number);
* @param session_number Session to send on.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_ai_entermenu(en50221_app_ai ai, uint16_t session_number);
extern int en50221_app_ai_entermenu(struct en50221_app_ai *ai,
uint16_t session_number);
/**
* Pass data received for this resource into it for parsing.
@ -116,14 +123,14 @@ extern int en50221_app_ai_entermenu(en50221_app_ai ai, uint16_t session_number);
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_ai_message(en50221_app_ai ai,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_ai_message(struct en50221_app_ai *ai,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -28,152 +28,153 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_auth_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_auth {
struct en50221_app_send_functions *funcs;
en50221_app_auth_request_callback callback;
void *callback_arg;
en50221_app_auth_request_callback callback;
void *callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_auth_parse_request(struct en50221_app_auth_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_auth_parse_request(struct en50221_app_auth *private,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_auth en50221_app_auth_create(struct en50221_app_send_functions *funcs)
struct en50221_app_auth *en50221_app_auth_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_auth_private *private = NULL;
struct en50221_app_auth *auth = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_auth_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->callback = NULL;
// create structure and set it up
auth = malloc(sizeof(struct en50221_app_auth));
if (auth == NULL) {
return NULL;
}
auth->funcs = funcs;
auth->callback = NULL;
pthread_mutex_init(&private->lock, NULL);
pthread_mutex_init(&auth->lock, NULL);
// done
return private;
// done
return auth;
}
void en50221_app_auth_destroy(en50221_app_auth auth)
void en50221_app_auth_destroy(struct en50221_app_auth *auth)
{
struct en50221_app_auth_private *private = (struct en50221_app_auth_private *) auth;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&auth->lock);
free(auth);
}
void en50221_app_auth_register_request_callback(en50221_app_auth auth,
en50221_app_auth_request_callback callback, void *arg)
void en50221_app_auth_register_request_callback(struct en50221_app_auth *auth,
en50221_app_auth_request_callback callback, void *arg)
{
struct en50221_app_auth_private *private = (struct en50221_app_auth_private *) auth;
pthread_mutex_lock(&private->lock);
private->callback = callback;
private->callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&auth->lock);
auth->callback = callback;
auth->callback_arg = arg;
pthread_mutex_unlock(&auth->lock);
}
int en50221_app_auth_send(en50221_app_auth auth,
uint16_t session_number,
uint16_t auth_protocol_id, uint8_t *auth_data,
uint32_t auth_data_length)
int en50221_app_auth_send(struct en50221_app_auth *auth,
uint16_t session_number,
uint16_t auth_protocol_id, uint8_t * auth_data,
uint32_t auth_data_length)
{
struct en50221_app_auth_private *private = (struct en50221_app_auth_private *) auth;
uint8_t buf[10];
// the header
buf[0] = (TAG_AUTH_RESP >> 16) & 0xFF;
buf[1] = (TAG_AUTH_RESP >> 8) & 0xFF;
buf[2] = TAG_AUTH_RESP & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(auth_data_length+2, buf+3, 3)) < 0) {
return -1;
}
// the phase_id
buf[3+length_field_len] = auth_protocol_id>>8;
buf[3+length_field_len+1] = auth_protocol_id;
// build the iovecs
struct iovec iov[2];
iov[0].iov_base = buf;
iov[0].iov_len = 3+length_field_len+2;
iov[1].iov_base = auth_data;
iov[1].iov_len = auth_data_length;
// sendit
return private->funcs->send_datav(private->funcs->arg, session_number, iov, 2);
uint8_t buf[10];
// the header
buf[0] = (TAG_AUTH_RESP >> 16) & 0xFF;
buf[1] = (TAG_AUTH_RESP >> 8) & 0xFF;
buf[2] = TAG_AUTH_RESP & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(auth_data_length + 2, buf + 3, 3)) < 0) {
return -1;
}
// the phase_id
buf[3 + length_field_len] = auth_protocol_id >> 8;
buf[3 + length_field_len + 1] = auth_protocol_id;
// build the iovecs
struct iovec iov[2];
iov[0].iov_base = buf;
iov[0].iov_len = 3 + length_field_len + 2;
iov[1].iov_base = auth_data;
iov[1].iov_len = auth_data_length;
// sendit
return auth->funcs->send_datav(auth->funcs->arg, session_number,
iov, 2);
}
int en50221_app_auth_message(en50221_app_auth auth,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_auth_message(struct en50221_app_auth *auth,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_auth_private *private = (struct en50221_app_auth_private *) auth;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_AUTH_REQ:
return en50221_app_auth_parse_request(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_AUTH_REQ:
return en50221_app_auth_parse_request(auth, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
static int en50221_app_auth_parse_request(struct en50221_app_auth_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_auth_parse_request(struct en50221_app_auth *auth,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length < 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length-length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *auth_data = data + length_field_len;
// process it
uint16_t auth_protocol_id = (auth_data[0]<<8) | auth_data[1];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_auth_request_callback cb = private->callback;
void *cb_arg = private->callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, auth_protocol_id, auth_data+2, asn_data_length-2);
}
return 0;
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length < 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *auth_data = data + length_field_len;
// process it
uint16_t auth_protocol_id = (auth_data[0] << 8) | auth_data[1];
// tell the app
pthread_mutex_lock(&auth->lock);
en50221_app_auth_request_callback cb = auth->callback;
void *cb_arg = auth->callback_arg;
pthread_mutex_unlock(&auth->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number,
auth_protocol_id, auth_data + 2,
asn_data_length - 2);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_auth_H__
#define __EN50221_APPLICATION_auth_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -46,14 +45,17 @@ extern "C"
* @param auth_data_lenghth Number of bytes.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_auth_request_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint16_t auth_protcol_id, uint8_t *auth_data,
uint32_t auth_data_length);
typedef int (*en50221_app_auth_request_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint16_t auth_protcol_id,
uint8_t *auth_data,
uint32_t auth_data_length);
/**
* Opaque type representing a auth resource.
*/
typedef void *en50221_app_auth;
struct en50221_app_auth;
/**
* Create an instance of the auth resource.
@ -61,14 +63,14 @@ typedef void *en50221_app_auth;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_auth en50221_app_auth_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_auth *en50221_app_auth_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the auth resource.
*
* @param auth Instance to destroy.
*/
extern void en50221_app_auth_destroy(en50221_app_auth auth);
extern void en50221_app_auth_destroy(struct en50221_app_auth *auth);
/**
* Register the callback for when we receive a request.
@ -77,8 +79,9 @@ extern void en50221_app_auth_destroy(en50221_app_auth auth);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_auth_register_request_callback(en50221_app_auth auth,
en50221_app_auth_request_callback callback, void *arg);
extern void en50221_app_auth_register_request_callback(struct en50221_app_auth *auth,
en50221_app_auth_request_callback callback,
void *arg);
/**
* Send an auth response to the CAM.
@ -90,10 +93,11 @@ extern void en50221_app_auth_register_request_callback(en50221_app_auth auth,
* @param auth_data_length Number of bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_auth_send(en50221_app_auth auth,
uint16_t session_number,
uint16_t auth_protocol_id, uint8_t *auth_data,
uint32_t auth_data_length);
extern int en50221_app_auth_send(struct en50221_app_auth *auth,
uint16_t session_number,
uint16_t auth_protocol_id,
uint8_t *auth_data,
uint32_t auth_data_length);
/**
* Pass data received for this resource into it for parsing.
@ -106,14 +110,14 @@ extern int en50221_app_auth_send(en50221_app_auth auth,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_auth_message(en50221_app_auth auth,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_auth_message(struct en50221_app_auth *auth,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_ca_H__
#define __EN50221_APPLICATION_ca_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -60,24 +59,24 @@ extern "C"
* PMT reply structure.
*/
struct en50221_app_pmt_reply {
uint16_t program_number;
EBIT3(uint8_t reserved_1 : 2; ,
uint8_t version_number : 5; ,
uint8_t current_next_indicator : 1; )
EBIT2(uint8_t CA_enable_flag : 1; ,
uint8_t CA_enable : 7; )
/* struct en50221_app_pmt_stream streams[] */
} __attribute__((packed));
uint16_t program_number;
EBIT3(uint8_t reserved_1 : 2;,
uint8_t version_number : 5;,
uint8_t current_next_indicator : 1;);
EBIT2(uint8_t CA_enable_flag : 1;,
uint8_t CA_enable : 7;);
/* struct en50221_app_pmt_stream streams[] */
} __attribute__ ((packed));
/**
* A stream within a pmt reply structure.
*/
struct en50221_app_pmt_stream {
EBIT2(uint16_t reserved_1 : 3; ,
uint16_t es_pid :13; )
EBIT2(uint8_t CA_enable_flag : 1; ,
uint8_t CA_enable : 7; )
} __attribute__((packed));
EBIT2(uint16_t reserved_1 : 3;,
uint16_t es_pid :13;);
EBIT2(uint8_t CA_enable_flag : 1;,
uint8_t CA_enable : 7;);
} __attribute__ ((packed));
/**
* Convenience iterator for the streams field of the en50221_app_pmt_reply structure.
@ -102,9 +101,11 @@ struct en50221_app_pmt_stream {
* @param ca_ids Pointer to list of ca_system_ids.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_ca_info_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint32_t ca_id_count,
uint16_t *ca_ids);
typedef int (*en50221_app_ca_info_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint32_t ca_id_count,
uint16_t * ca_ids);
/**
* Type definition for pmt_reply - called when we receive a pmt_reply.
@ -116,14 +117,16 @@ typedef int (*en50221_app_ca_info_callback)(void *arg, uint8_t slot_id, uint16_t
* @param reply_size Total size of the struct en50221_app_pmt_reply in bytes.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_ca_pmt_reply_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
struct en50221_app_pmt_reply *reply,
uint32_t reply_size);
typedef int (*en50221_app_ca_pmt_reply_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
struct en50221_app_pmt_reply *reply,
uint32_t reply_size);
/**
* Opaque type representing a ca resource.
*/
typedef void *en50221_app_ca;
struct en50221_app_ca;
/**
* Create an instance of the ca resource.
@ -131,14 +134,14 @@ typedef void *en50221_app_ca;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_ca en50221_app_ca_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_ca *en50221_app_ca_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the ca resource.
*
* @param ca Instance to destroy.
*/
extern void en50221_app_ca_destroy(en50221_app_ca ca);
extern void en50221_app_ca_destroy(struct en50221_app_ca *ca);
/**
* Register the callback for when we receive a ca info.
@ -147,8 +150,9 @@ extern void en50221_app_ca_destroy(en50221_app_ca ca);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_ca_register_info_callback(en50221_app_ca ca,
en50221_app_ca_info_callback callback, void *arg);
extern void en50221_app_ca_register_info_callback(struct en50221_app_ca *ca,
en50221_app_ca_info_callback callback,
void *arg);
/**
* Register the callback for when we receive a pmt_reply.
@ -157,8 +161,9 @@ extern void en50221_app_ca_register_info_callback(en50221_app_ca ca,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_ca_register_pmt_reply_callback(en50221_app_ca ca,
en50221_app_ca_pmt_reply_callback callback, void *arg);
extern void en50221_app_ca_register_pmt_reply_callback(struct en50221_app_ca *ca,
en50221_app_ca_pmt_reply_callback callback,
void *arg);
/**
* Send a ca_info_req to the CAM.
@ -167,8 +172,8 @@ extern void en50221_app_ca_register_pmt_reply_callback(en50221_app_ca ca,
* @param session_number Session number to send it on.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_ca_info_enq(en50221_app_ca ca,
uint16_t session_number);
extern int en50221_app_ca_info_enq(struct en50221_app_ca *ca,
uint16_t session_number);
/**
* Send a ca_pmt structure to the CAM.
@ -179,10 +184,10 @@ extern int en50221_app_ca_info_enq(en50221_app_ca ca,
* @param ca_pmt_length Length of ca_pmt structure in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_ca_pmt(en50221_app_ca ca,
uint16_t session_number,
uint8_t *ca_pmt,
uint32_t ca_pmt_length);
extern int en50221_app_ca_pmt(struct en50221_app_ca *ca,
uint16_t session_number,
uint8_t * ca_pmt,
uint32_t ca_pmt_length);
/**
* Transform a libucsi PMT into a binary structure for sending to a CAM.
@ -197,10 +202,11 @@ extern int en50221_app_ca_pmt(en50221_app_ca ca,
* @return Number of bytes used, or -1 on error.
*/
extern int en50221_ca_format_pmt(struct mpeg_pmt_section *pmt,
uint8_t *data,
uint32_t data_length,
int move_ca_descriptors,
uint8_t ca_pmt_list_management, uint8_t ca_pmt_cmd_id);
uint8_t * data,
uint32_t data_length,
int move_ca_descriptors,
uint8_t ca_pmt_list_management,
uint8_t ca_pmt_cmd_id);
/**
* Pass data received for this resource into it for parsing.
@ -213,38 +219,42 @@ extern int en50221_ca_format_pmt(struct mpeg_pmt_section *pmt,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_ca_message(en50221_app_ca ca,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_ca_message(struct en50221_app_ca *ca,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
static inline struct en50221_app_pmt_stream *
en50221_app_pmt_reply_streams_first(struct en50221_app_pmt_reply *reply, uint32_t reply_size)
en50221_app_pmt_reply_streams_first(struct en50221_app_pmt_reply *reply,
uint32_t reply_size)
{
uint32_t pos = sizeof(struct en50221_app_pmt_reply);
uint32_t pos = sizeof(struct en50221_app_pmt_reply);
if (pos >= reply_size)
return NULL;
if (pos >= reply_size)
return NULL;
return (struct en50221_app_pmt_stream *)((uint8_t *)reply+ pos);
return (struct en50221_app_pmt_stream *) ((uint8_t *) reply + pos);
}
static inline struct en50221_app_pmt_stream *
en50221_app_pmt_reply_streams_next(struct en50221_app_pmt_reply * reply,
struct en50221_app_pmt_stream * pos,
uint32_t reply_size)
en50221_app_pmt_reply_streams_next(struct en50221_app_pmt_reply *reply,
struct en50221_app_pmt_stream *pos,
uint32_t reply_size)
{
uint8_t *end = (uint8_t*) reply + reply_size;
uint8_t *next = (uint8_t *) pos + sizeof(struct en50221_app_pmt_stream);
uint8_t *end = (uint8_t *) reply + reply_size;
uint8_t *next =
(uint8_t *) pos +
sizeof(struct en50221_app_pmt_stream);
if (next >= end)
return NULL;
if (next >= end)
return NULL;
return (struct en50221_app_pmt_stream *) next;
return (struct en50221_app_pmt_stream *) next;
}
#ifdef __cplusplus

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -29,108 +29,109 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_datetime_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_datetime {
struct en50221_app_send_functions *funcs;
en50221_app_datetime_enquiry_callback callback;
void *callback_arg;
en50221_app_datetime_enquiry_callback callback;
void *callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_datetime_parse_enquiry(struct en50221_app_datetime_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_datetime_parse_enquiry(struct en50221_app_datetime *datetime,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_datetime en50221_app_datetime_create(struct en50221_app_send_functions *funcs)
struct en50221_app_datetime *en50221_app_datetime_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_datetime_private *private = NULL;
struct en50221_app_datetime *datetime = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_datetime_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->callback = NULL;
// create structure and set it up
datetime = malloc(sizeof(struct en50221_app_datetime));
if (datetime == NULL) {
return NULL;
}
datetime->funcs = funcs;
datetime->callback = NULL;
pthread_mutex_init(&private->lock, NULL);
pthread_mutex_init(&datetime->lock, NULL);
// done
return private;
// done
return datetime;
}
void en50221_app_datetime_destroy(en50221_app_datetime datetime)
void en50221_app_datetime_destroy(struct en50221_app_datetime *datetime)
{
struct en50221_app_datetime_private *private = (struct en50221_app_datetime_private *) datetime;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&datetime->lock);
free(datetime);
}
void en50221_app_datetime_register_enquiry_callback(en50221_app_datetime datetime,
en50221_app_datetime_enquiry_callback callback, void *arg)
void en50221_app_datetime_register_enquiry_callback(struct en50221_app_datetime *datetime,
en50221_app_datetime_enquiry_callback callback,
void *arg)
{
struct en50221_app_datetime_private *private = (struct en50221_app_datetime_private *) datetime;
pthread_mutex_lock(&private->lock);
private->callback = callback;
private->callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&datetime->lock);
datetime->callback = callback;
datetime->callback_arg = arg;
pthread_mutex_unlock(&datetime->lock);
}
int en50221_app_datetime_send(en50221_app_datetime datetime,
uint16_t session_number,
time_t utc_time,
int time_offset)
int en50221_app_datetime_send(struct en50221_app_datetime *datetime,
uint16_t session_number,
time_t utc_time, int time_offset)
{
struct en50221_app_datetime_private *private = (struct en50221_app_datetime_private *) datetime;
uint8_t data[11];
int data_length;
data[0] = (TAG_DATE_TIME >> 16) & 0xFF;
data[1] = (TAG_DATE_TIME >> 8) & 0xFF;
data[2] = TAG_DATE_TIME & 0xFF;
if (time_offset != -1) {
data[3] = 7;
unixtime_to_dvbdate(utc_time, data+4);
data[9] = time_offset >> 8;
data[10] = time_offset;
data_length = 11;
} else {
data[3] = 5;
unixtime_to_dvbdate(utc_time, data+4);
data_length = 9;
}
return private->funcs->send_data(private->funcs->arg, session_number, data, data_length);
uint8_t data[11];
int data_length;
data[0] = (TAG_DATE_TIME >> 16) & 0xFF;
data[1] = (TAG_DATE_TIME >> 8) & 0xFF;
data[2] = TAG_DATE_TIME & 0xFF;
if (time_offset != -1) {
data[3] = 7;
unixtime_to_dvbdate(utc_time, data + 4);
data[9] = time_offset >> 8;
data[10] = time_offset;
data_length = 11;
} else {
data[3] = 5;
unixtime_to_dvbdate(utc_time, data + 4);
data_length = 9;
}
return datetime->funcs->send_data(datetime->funcs->arg,
session_number, data,
data_length);
}
int en50221_app_datetime_message(en50221_app_datetime datetime,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_datetime_message(struct en50221_app_datetime *datetime,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_datetime_private *private = (struct en50221_app_datetime_private *) datetime;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_DATE_TIME_ENQUIRY:
return en50221_app_datetime_parse_enquiry(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_DATE_TIME_ENQUIRY:
return en50221_app_datetime_parse_enquiry(datetime,
slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
@ -142,28 +143,31 @@ int en50221_app_datetime_message(en50221_app_datetime datetime,
static int en50221_app_datetime_parse_enquiry(struct en50221_app_datetime_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_datetime_parse_enquiry(struct en50221_app_datetime *datetime,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// validate data
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t response_interval = data[1];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_datetime_enquiry_callback cb = private->callback;
void *cb_arg = private->callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, response_interval);
}
return 0;
// validate data
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t response_interval = data[1];
// tell the app
pthread_mutex_lock(&datetime->lock);
en50221_app_datetime_enquiry_callback cb = datetime->callback;
void *cb_arg = datetime->callback_arg;
pthread_mutex_unlock(&datetime->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number,
response_interval);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_DATETIME_H__
#define __EN50221_APPLICATION_DATETIME_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -44,13 +43,15 @@ extern "C"
* @param response_interval Response interval requested by CAM.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_datetime_enquiry_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t response_interval);
typedef int (*en50221_app_datetime_enquiry_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t response_interval);
/**
* Opaque type representing a datetime resource.
*/
typedef void *en50221_app_datetime;
struct en50221_app_datetime;
/**
* Create an instance of the datetime resource.
@ -58,14 +59,15 @@ typedef void *en50221_app_datetime;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_datetime en50221_app_datetime_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_datetime
*en50221_app_datetime_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the datetime resource.
*
* @param datetime Instance to destroy.
*/
extern void en50221_app_datetime_destroy(en50221_app_datetime datetime);
extern void en50221_app_datetime_destroy(struct en50221_app_datetime *datetime);
/**
* Register the callback for when we receive a enquiry request.
@ -74,8 +76,9 @@ extern void en50221_app_datetime_destroy(en50221_app_datetime datetime);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_datetime_register_enquiry_callback(en50221_app_datetime datetime,
en50221_app_datetime_enquiry_callback callback, void *arg);
extern void en50221_app_datetime_register_enquiry_callback(struct en50221_app_datetime *datetime,
en50221_app_datetime_enquiry_callback callback,
void *arg);
/**
* Send the time to the CAM.
@ -87,10 +90,10 @@ extern void en50221_app_datetime_register_enquiry_callback(en50221_app_datetime
* UTC and local time in minutes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_datetime_send(en50221_app_datetime datetime,
uint16_t session_number,
time_t utc_time,
int time_offset);
extern int en50221_app_datetime_send(struct en50221_app_datetime *datetime,
uint16_t session_number,
time_t utc_time,
int time_offset);
/**
* Pass data received for this resource into it for parsing.
@ -103,14 +106,14 @@ extern int en50221_app_datetime_send(en50221_app_datetime datetime,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_datetime_message(en50221_app_datetime datetime,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_datetime_message(struct en50221_app_datetime *datetime,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -28,137 +28,144 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_dvb_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_dvb {
struct en50221_app_send_functions *funcs;
en50221_app_dvb_tune_callback tune_callback;
void *tune_callback_arg;
en50221_app_dvb_tune_callback tune_callback;
void *tune_callback_arg;
en50221_app_dvb_replace_callback replace_callback;
void *replace_callback_arg;
en50221_app_dvb_replace_callback replace_callback;
void *replace_callback_arg;
en50221_app_dvb_clear_replace_callback clear_replace_callback;
void *clear_replace_callback_arg;
en50221_app_dvb_clear_replace_callback clear_replace_callback;
void *clear_replace_callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_dvb_parse_tune(struct en50221_app_dvb_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_dvb_parse_tune(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
static int en50221_app_dvb_parse_replace(struct en50221_app_dvb_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_dvb_parse_replace(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_dvb en50221_app_dvb_create(struct en50221_app_send_functions *funcs)
struct en50221_app_dvb *en50221_app_dvb_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_dvb_private *private = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_dvb_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->tune_callback = NULL;
private->replace_callback = NULL;
private->clear_replace_callback = NULL;
pthread_mutex_init(&private->lock, NULL);
// done
return private;
struct en50221_app_dvb *dvb = NULL;
// create structure and set it up
dvb = malloc(sizeof(struct en50221_app_dvb));
if (dvb == NULL) {
return NULL;
}
dvb->funcs = funcs;
dvb->tune_callback = NULL;
dvb->replace_callback = NULL;
dvb->clear_replace_callback = NULL;
pthread_mutex_init(&dvb->lock, NULL);
// done
return dvb;
}
void en50221_app_dvb_destroy(en50221_app_dvb dvb)
void en50221_app_dvb_destroy(struct en50221_app_dvb *dvb)
{
struct en50221_app_dvb_private *private = (struct en50221_app_dvb_private *) dvb;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&dvb->lock);
free(dvb);
}
void en50221_app_dvb_register_tune_callback(en50221_app_dvb dvb,
en50221_app_dvb_tune_callback callback, void *arg)
void en50221_app_dvb_register_tune_callback(struct en50221_app_dvb *dvb,
en50221_app_dvb_tune_callback callback,
void *arg)
{
struct en50221_app_dvb_private *private = (struct en50221_app_dvb_private *) dvb;
pthread_mutex_lock(&private->lock);
private->tune_callback = callback;
private->tune_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&dvb->lock);
dvb->tune_callback = callback;
dvb->tune_callback_arg = arg;
pthread_mutex_unlock(&dvb->lock);
}
void en50221_app_dvb_register_replace_callback(en50221_app_dvb dvb,
en50221_app_dvb_replace_callback callback, void *arg)
void en50221_app_dvb_register_replace_callback(struct en50221_app_dvb *dvb,
en50221_app_dvb_replace_callback callback,
void *arg)
{
struct en50221_app_dvb_private *private = (struct en50221_app_dvb_private *) dvb;
pthread_mutex_lock(&private->lock);
private->replace_callback = callback;
private->replace_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&dvb->lock);
dvb->replace_callback = callback;
dvb->replace_callback_arg = arg;
pthread_mutex_unlock(&dvb->lock);
}
void en50221_app_dvb_register_clear_replace_callback(en50221_app_dvb dvb,
en50221_app_dvb_clear_replace_callback callback, void *arg)
void en50221_app_dvb_register_clear_replace_callback(struct en50221_app_dvb *dvb,
en50221_app_dvb_clear_replace_callback callback,
void *arg)
{
struct en50221_app_dvb_private *private = (struct en50221_app_dvb_private *) dvb;
pthread_mutex_lock(&private->lock);
private->clear_replace_callback = callback;
private->clear_replace_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&dvb->lock);
dvb->clear_replace_callback = callback;
dvb->clear_replace_callback_arg = arg;
pthread_mutex_unlock(&dvb->lock);
}
int en50221_app_dvb_ask_release(en50221_app_dvb dvb, uint16_t session_number)
int en50221_app_dvb_ask_release(struct en50221_app_dvb *dvb,
uint16_t session_number)
{
struct en50221_app_dvb_private *private = (struct en50221_app_dvb_private *) dvb;
uint8_t data[4];
uint8_t data[4];
data[0] = (TAG_ASK_RELEASE >> 16) & 0xFF;
data[1] = (TAG_ASK_RELEASE >> 8) & 0xFF;
data[2] = TAG_ASK_RELEASE & 0xFF;
data[3] = 0;
data[0] = (TAG_ASK_RELEASE >> 16) & 0xFF;
data[1] = (TAG_ASK_RELEASE >> 8) & 0xFF;
data[2] = TAG_ASK_RELEASE & 0xFF;
data[3] = 0;
return private->funcs->send_data(private->funcs->arg, session_number, data, 4);
return dvb->funcs->send_data(dvb->funcs->arg, session_number, data, 4);
}
int en50221_app_dvb_message(en50221_app_dvb dvb,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_dvb_message(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_dvb_private *private = (struct en50221_app_dvb_private *) dvb;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_TUNE:
return en50221_app_dvb_parse_tune(private, slot_id, session_number, data+3, data_length-3);
case TAG_REPLACE:
return en50221_app_dvb_parse_replace(private, slot_id, session_number, data+3, data_length-3);
case TAG_CLEAR_REPLACE:
return en50221_app_dvb_parse_clear_replace(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_TUNE:
return en50221_app_dvb_parse_tune(dvb, slot_id,
session_number, data + 3,
data_length - 3);
case TAG_REPLACE:
return en50221_app_dvb_parse_replace(dvb, slot_id,
session_number,
data + 3,
data_length - 3);
case TAG_CLEAR_REPLACE:
return en50221_app_dvb_parse_clear_replace(dvb, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
@ -170,94 +177,106 @@ int en50221_app_dvb_message(en50221_app_dvb dvb,
static int en50221_app_dvb_parse_tune(struct en50221_app_dvb_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_dvb_parse_tune(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data, uint32_t data_length)
{
// validate data
if (data_length < 9) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 8) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *tune_data = data+1;
// parse it
uint16_t network_id = (tune_data[0] << 8) | tune_data[1];
uint16_t original_network_id = (tune_data[2] << 8) | tune_data[3];
uint16_t transport_stream_id = (tune_data[4] << 8) | tune_data[5];
uint16_t service_id = (tune_data[6] << 8) | tune_data[7];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_dvb_tune_callback cb = private->tune_callback;
void *cb_arg = private->tune_callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, network_id, original_network_id, transport_stream_id, service_id);
}
return 0;
// validate data
if (data_length < 9) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 8) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *tune_data = data + 1;
// parse it
uint16_t network_id = (tune_data[0] << 8) | tune_data[1];
uint16_t original_network_id = (tune_data[2] << 8) | tune_data[3];
uint16_t transport_stream_id = (tune_data[4] << 8) | tune_data[5];
uint16_t service_id = (tune_data[6] << 8) | tune_data[7];
// tell the app
pthread_mutex_lock(&dvb->lock);
en50221_app_dvb_tune_callback cb = dvb->tune_callback;
void *cb_arg = dvb->tune_callback_arg;
pthread_mutex_unlock(&dvb->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, network_id,
original_network_id, transport_stream_id,
service_id);
}
return 0;
}
static int en50221_app_dvb_parse_replace(struct en50221_app_dvb_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_dvb_parse_replace(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// validate data
if (data_length < 6) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 5) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *replace_data = data+1;
// parse it
uint8_t replacement_ref = replace_data[0];
uint16_t replace_pid = ((replace_data[1] & 0x1f)<<8) | replace_data[2];
uint16_t replacement_pid = ((replace_data[3] & 0x1f)<<8) | replace_data[4];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_dvb_replace_callback cb = private->replace_callback;
void *cb_arg = private->replace_callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, replacement_ref, replace_pid, replacement_pid);
}
return 0;
// validate data
if (data_length < 6) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 5) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *replace_data = data + 1;
// parse it
uint8_t replacement_ref = replace_data[0];
uint16_t replace_pid =
((replace_data[1] & 0x1f) << 8) | replace_data[2];
uint16_t replacement_pid =
((replace_data[3] & 0x1f) << 8) | replace_data[4];
// tell the app
pthread_mutex_lock(&dvb->lock);
en50221_app_dvb_replace_callback cb = dvb->replace_callback;
void *cb_arg = dvb->replace_callback_arg;
pthread_mutex_unlock(&dvb->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, replacement_ref,
replace_pid, replacement_pid);
}
return 0;
}
static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// validate data
if (data_length < 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *replace_data = data+1;
// parse it
uint8_t replacement_ref = replace_data[0];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_dvb_clear_replace_callback cb = private->clear_replace_callback;
void *cb_arg = private->clear_replace_callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, replacement_ref);
}
return 0;
// validate data
if (data_length < 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *replace_data = data + 1;
// parse it
uint8_t replacement_ref = replace_data[0];
// tell the app
pthread_mutex_lock(&dvb->lock);
en50221_app_dvb_clear_replace_callback cb =
dvb->clear_replace_callback;
void *cb_arg = dvb->clear_replace_callback_arg;
pthread_mutex_unlock(&dvb->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number,
replacement_ref);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_DVB_H__
#define __EN50221_APPLICATION_DVB_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -48,9 +47,13 @@ extern "C"
* @param service_id Service id requested by CAM.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_dvb_tune_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint16_t network_id, uint32_t original_network_id,
uint16_t transport_stream_id, uint16_t service_id);
typedef int (*en50221_app_dvb_tune_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint16_t network_id,
uint32_t original_network_id,
uint16_t transport_stream_id,
uint16_t service_id);
/**
* Type definition for replace - called when we receive a replace request from a CAM.
@ -63,9 +66,12 @@ typedef int (*en50221_app_dvb_tune_callback)(void *arg, uint8_t slot_id, uint16_
* @param replacement_pid PID to replace it with.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_dvb_replace_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t replacement_ref,
uint16_t replaced_pid, uint16_t replacement_pid);
typedef int (*en50221_app_dvb_replace_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t replacement_ref,
uint16_t replaced_pid,
uint16_t replacement_pid);
/**
@ -77,14 +83,16 @@ typedef int (*en50221_app_dvb_replace_callback)(void *arg, uint8_t slot_id, uint
* @param replacement_ref Replacement ref.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_dvb_clear_replace_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t replacement_ref);
typedef int (*en50221_app_dvb_clear_replace_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t replacement_ref);
/**
* Opaque type representing a dvb resource.
*/
typedef void *en50221_app_dvb;
struct en50221_app_dvb;
/**
* Create an instance of the dvb resource.
@ -92,14 +100,14 @@ typedef void *en50221_app_dvb;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_dvb en50221_app_dvb_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_dvb *en50221_app_dvb_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the dvb resource.
*
* @param dvb Instance to destroy.
*/
extern void en50221_app_dvb_destroy(en50221_app_dvb dvb);
extern void en50221_app_dvb_destroy(struct en50221_app_dvb *dvb);
/**
* Register the callback for when we receive a tune request.
@ -108,8 +116,9 @@ extern void en50221_app_dvb_destroy(en50221_app_dvb dvb);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_dvb_register_tune_callback(en50221_app_dvb dvb,
en50221_app_dvb_tune_callback callback, void *arg);
extern void en50221_app_dvb_register_tune_callback(struct en50221_app_dvb *dvb,
en50221_app_dvb_tune_callback callback,
void *arg);
/**
* Register the callback for when we receive a replace request.
@ -118,8 +127,9 @@ extern void en50221_app_dvb_register_tune_callback(en50221_app_dvb dvb,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_dvb_register_replace_callback(en50221_app_dvb dvb,
en50221_app_dvb_replace_callback callback, void *arg);
extern void en50221_app_dvb_register_replace_callback(struct en50221_app_dvb *dvb,
en50221_app_dvb_replace_callback callback,
void *arg);
/**
* Register the callback for when we receive a clear replace request.
@ -128,8 +138,9 @@ extern void en50221_app_dvb_register_replace_callback(en50221_app_dvb dvb,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_dvb_register_clear_replace_callback(en50221_app_dvb dvb,
en50221_app_dvb_clear_replace_callback callback, void *arg);
extern void en50221_app_dvb_register_clear_replace_callback(struct en50221_app_dvb *dvb,
en50221_app_dvb_clear_replace_callback callback,
void *arg);
/**
* Send an ask release request to the CAM.
@ -138,7 +149,8 @@ extern void en50221_app_dvb_register_clear_replace_callback(en50221_app_dvb dvb,
* @param session_number Session number to send it on.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_dvb_ask_release(en50221_app_dvb dvb, uint16_t session_number);
extern int en50221_app_dvb_ask_release(struct en50221_app_dvb *dvb,
uint16_t session_number);
/**
* Pass data received for this resource into it for parsing.
@ -151,14 +163,14 @@ extern int en50221_app_dvb_ask_release(en50221_app_dvb dvb, uint16_t session_num
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_dvb_message(en50221_app_dvb dvb,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_dvb_message(struct en50221_app_dvb *dvb,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -29,138 +29,139 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_epg_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_epg {
struct en50221_app_send_functions *funcs;
en50221_app_epg_reply_callback callback;
void *callback_arg;
en50221_app_epg_reply_callback callback;
void *callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_epg_parse_reply(struct en50221_app_epg_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_epg_parse_reply(struct en50221_app_epg *private,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_epg en50221_app_epg_create(struct en50221_app_send_functions *funcs)
struct en50221_app_epg *en50221_app_epg_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_epg_private *private = NULL;
struct en50221_app_epg *epg = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_epg_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->callback = NULL;
// create structure and set it up
epg = malloc(sizeof(struct en50221_app_epg));
if (epg == NULL) {
return NULL;
}
epg->funcs = funcs;
epg->callback = NULL;
pthread_mutex_init(&private->lock, NULL);
pthread_mutex_init(&epg->lock, NULL);
// done
return private;
// done
return epg;
}
void en50221_app_epg_destroy(en50221_app_epg epg)
void en50221_app_epg_destroy(struct en50221_app_epg *epg)
{
struct en50221_app_epg_private *private = (struct en50221_app_epg_private *) epg;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&epg->lock);
free(epg);
}
void en50221_app_epg_register_enquiry_callback(en50221_app_epg epg,
en50221_app_epg_reply_callback callback, void *arg)
void en50221_app_epg_register_enquiry_callback(struct en50221_app_epg *epg,
en50221_app_epg_reply_callback callback,
void *arg)
{
struct en50221_app_epg_private *private = (struct en50221_app_epg_private *) epg;
pthread_mutex_lock(&private->lock);
private->callback = callback;
private->callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&epg->lock);
epg->callback = callback;
epg->callback_arg = arg;
pthread_mutex_unlock(&epg->lock);
}
int en50221_app_epg_enquire(en50221_app_epg epg,
uint16_t session_number,
uint8_t command_id,
uint16_t network_id,
uint16_t original_network_id,
uint16_t transport_stream_id,
uint16_t service_id,
uint16_t event_id)
int en50221_app_epg_enquire(struct en50221_app_epg *epg,
uint16_t session_number,
uint8_t command_id,
uint16_t network_id,
uint16_t original_network_id,
uint16_t transport_stream_id,
uint16_t service_id, uint16_t event_id)
{
struct en50221_app_epg_private *private = (struct en50221_app_epg_private *) epg;
uint8_t data[15];
data[0] = (TAG_EPG_ENQUIRY >> 16) & 0xFF;
data[1] = (TAG_EPG_ENQUIRY >> 8) & 0xFF;
data[2] = TAG_EPG_ENQUIRY & 0xFF;
data[3] = 11;
data[4] = command_id;
data[5] = network_id >> 8;
data[6] = network_id;
data[7] = original_network_id >> 8;
data[8] = original_network_id;
data[9] = transport_stream_id >> 8;
data[10] = transport_stream_id;
data[11] = service_id >> 8;
data[12] = service_id;
data[13] = event_id >> 8;
data[14] = event_id;
return private->funcs->send_data(private->funcs->arg, session_number, data, 15);
uint8_t data[15];
data[0] = (TAG_EPG_ENQUIRY >> 16) & 0xFF;
data[1] = (TAG_EPG_ENQUIRY >> 8) & 0xFF;
data[2] = TAG_EPG_ENQUIRY & 0xFF;
data[3] = 11;
data[4] = command_id;
data[5] = network_id >> 8;
data[6] = network_id;
data[7] = original_network_id >> 8;
data[8] = original_network_id;
data[9] = transport_stream_id >> 8;
data[10] = transport_stream_id;
data[11] = service_id >> 8;
data[12] = service_id;
data[13] = event_id >> 8;
data[14] = event_id;
return epg->funcs->send_data(epg->funcs->arg, session_number, data, 15);
}
int en50221_app_epg_message(en50221_app_epg epg,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_epg_message(struct en50221_app_epg *epg,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_epg_private *private = (struct en50221_app_epg_private *) epg;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_EPG_REPLY:
return en50221_app_epg_parse_reply(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
struct en50221_app_epg *private = (struct en50221_app_epg *) epg;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_EPG_REPLY:
return en50221_app_epg_parse_reply(private, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
static int en50221_app_epg_parse_reply(struct en50221_app_epg_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_epg_parse_reply(struct en50221_app_epg *epg,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// validate data
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t event_status = data[1];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_epg_reply_callback cb = private->callback;
void *cb_arg = private->callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, event_status);
}
return 0;
// validate data
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t event_status = data[1];
// tell the app
pthread_mutex_lock(&epg->lock);
en50221_app_epg_reply_callback cb = epg->callback;
void *cb_arg = epg->callback_arg;
pthread_mutex_unlock(&epg->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, event_status);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_epg_H__
#define __EN50221_APPLICATION_epg_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -57,13 +56,15 @@ extern "C"
* @param event_status One of the EPG_EVENTSTATUS_* values.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_epg_reply_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t event_status);
typedef int (*en50221_app_epg_reply_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t event_status);
/**
* Opaque type representing a epg resource.
*/
typedef void *en50221_app_epg;
struct en50221_app_epg;
/**
* Create an instance of the epg resource.
@ -71,14 +72,14 @@ typedef void *en50221_app_epg;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_epg en50221_app_epg_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_epg *en50221_app_epg_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the epg resource.
*
* @param epg Instance to destroy.
*/
extern void en50221_app_epg_destroy(en50221_app_epg epg);
extern void en50221_app_epg_destroy(struct en50221_app_epg *epg);
/**
* Register the callback for when we receive a enquiry response.
@ -87,8 +88,9 @@ extern void en50221_app_epg_destroy(en50221_app_epg epg);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_epg_register_reply_callback(en50221_app_epg epg,
en50221_app_epg_reply_callback callback, void *arg);
extern void en50221_app_epg_register_reply_callback(struct en50221_app_epg *epg,
en50221_app_epg_reply_callback callback,
void *arg);
/**
* Enquire about the entitlement status for an EPG entry.
@ -103,14 +105,14 @@ extern void en50221_app_epg_register_reply_callback(en50221_app_epg epg,
* @param event_id Event ID concerned.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_epg_enquire(en50221_app_epg epg,
uint16_t session_number,
uint8_t command_id,
uint16_t network_id,
uint16_t original_network_id,
uint16_t transport_stream_id,
uint16_t service_id,
uint16_t event_id);
extern int en50221_app_epg_enquire(struct en50221_app_epg *epg,
uint16_t session_number,
uint8_t command_id,
uint16_t network_id,
uint16_t original_network_id,
uint16_t transport_stream_id,
uint16_t service_id,
uint16_t event_id);
/**
* Pass data received for this resource into it for parsing.
@ -123,14 +125,14 @@ extern int en50221_app_epg_enquire(en50221_app_epg epg,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_epg_message(en50221_app_epg epg,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_epg_message(struct en50221_app_epg *epg,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -29,486 +29,505 @@
#include "asn_1.h"
struct en50221_app_lowspeed_session {
uint16_t session_number;
uint8_t *block_chain;
uint32_t block_length;
uint16_t session_number;
uint8_t *block_chain;
uint32_t block_length;
struct en50221_app_lowspeed_session *next;
struct en50221_app_lowspeed_session *next;
};
struct en50221_app_lowspeed_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_lowspeed {
struct en50221_app_send_functions *funcs;
en50221_app_lowspeed_command_callback command_callback;
void *command_callback_arg;
en50221_app_lowspeed_command_callback command_callback;
void *command_callback_arg;
en50221_app_lowspeed_send_callback send_callback;
void *send_callback_arg;
en50221_app_lowspeed_send_callback send_callback;
void *send_callback_arg;
struct en50221_app_lowspeed_session *sessions;
struct en50221_app_lowspeed_session *sessions;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_lowspeed_parse_connect_on_channel(struct en50221_app_lowspeed_command *command,
uint8_t *data,
int data_length);
static int en50221_app_lowspeed_parse_command(struct en50221_app_lowspeed_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_lowspeed_parse_send(struct en50221_app_lowspeed_private *private,
uint8_t slot_id, uint16_t session_number, int more_last,
uint8_t *data, uint32_t data_length);
en50221_app_lowspeed en50221_app_lowspeed_create(struct en50221_app_send_functions *funcs)
uint8_t *data,
int data_length);
static int en50221_app_lowspeed_parse_command(struct en50221_app_lowspeed *lowspeed,
uint8_t slot_id,
uint16_t session_number,
uint8_t *data,
uint32_t data_length);
static int en50221_app_lowspeed_parse_send(struct en50221_app_lowspeed *lowspeed,
uint8_t slot_id,
uint16_t session_number,
int more_last,
uint8_t *data,
uint32_t data_length);
struct en50221_app_lowspeed *en50221_app_lowspeed_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_lowspeed_private *private = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_lowspeed_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->command_callback = NULL;
private->send_callback = NULL;
private->sessions = NULL;
pthread_mutex_init(&private->lock, NULL);
// done
return private;
struct en50221_app_lowspeed *lowspeed = NULL;
// create structure and set it up
lowspeed = malloc(sizeof(struct en50221_app_lowspeed));
if (lowspeed == NULL) {
return NULL;
}
lowspeed->funcs = funcs;
lowspeed->command_callback = NULL;
lowspeed->send_callback = NULL;
lowspeed->sessions = NULL;
pthread_mutex_init(&lowspeed->lock, NULL);
// done
return lowspeed;
}
void en50221_app_lowspeed_destroy(en50221_app_lowspeed lowspeed)
void en50221_app_lowspeed_destroy(struct en50221_app_lowspeed *lowspeed)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
struct en50221_app_lowspeed_session *cur_s = private->sessions;
while(cur_s) {
struct en50221_app_lowspeed_session *next = cur_s->next;
if (cur_s->block_chain)
free(cur_s->block_chain);
free(cur_s);
cur_s = next;
}
pthread_mutex_destroy(&private->lock);
free(private);
struct en50221_app_lowspeed_session *cur_s = lowspeed->sessions;
while (cur_s) {
struct en50221_app_lowspeed_session *next = cur_s->next;
if (cur_s->block_chain)
free(cur_s->block_chain);
free(cur_s);
cur_s = next;
}
pthread_mutex_destroy(&lowspeed->lock);
free(lowspeed);
}
void en50221_app_lowspeed_clear_session(en50221_app_lowspeed lowspeed, uint16_t session_number)
void en50221_app_lowspeed_clear_session(struct en50221_app_lowspeed *lowspeed,
uint16_t session_number)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
pthread_mutex_lock(&private->lock);
struct en50221_app_lowspeed_session *cur_s = private->sessions;
struct en50221_app_lowspeed_session *prev_s = NULL;
while(cur_s) {
if (cur_s->session_number == session_number) {
if (cur_s->block_chain)
free(cur_s->block_chain);
if (prev_s) {
prev_s->next = cur_s->next;
} else {
private->sessions = cur_s->next;
}
free(cur_s);
return;
}
prev_s = cur_s;
cur_s=cur_s->next;
}
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&lowspeed->lock);
struct en50221_app_lowspeed_session *cur_s = lowspeed->sessions;
struct en50221_app_lowspeed_session *prev_s = NULL;
while (cur_s) {
if (cur_s->session_number == session_number) {
if (cur_s->block_chain)
free(cur_s->block_chain);
if (prev_s) {
prev_s->next = cur_s->next;
} else {
lowspeed->sessions = cur_s->next;
}
free(cur_s);
return;
}
prev_s = cur_s;
cur_s = cur_s->next;
}
pthread_mutex_unlock(&lowspeed->lock);
}
void en50221_app_lowspeed_register_command_callback(en50221_app_lowspeed lowspeed,
en50221_app_lowspeed_command_callback callback, void *arg)
void en50221_app_lowspeed_register_command_callback(struct en50221_app_lowspeed *lowspeed,
en50221_app_lowspeed_command_callback callback,
void *arg)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
pthread_mutex_lock(&private->lock);
private->command_callback = callback;
private->command_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&lowspeed->lock);
lowspeed->command_callback = callback;
lowspeed->command_callback_arg = arg;
pthread_mutex_unlock(&lowspeed->lock);
}
void en50221_app_lowspeed_register_send_callback(en50221_app_lowspeed lowspeed,
en50221_app_lowspeed_send_callback callback, void *arg)
void en50221_app_lowspeed_register_send_callback(struct en50221_app_lowspeed *lowspeed,
en50221_app_lowspeed_send_callback callback,
void *arg)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
pthread_mutex_lock(&private->lock);
private->send_callback = callback;
private->send_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&lowspeed->lock);
lowspeed->send_callback = callback;
lowspeed->send_callback_arg = arg;
pthread_mutex_unlock(&lowspeed->lock);
}
int en50221_app_lowspeed_send_comms_reply(en50221_app_lowspeed lowspeed,
uint16_t session_number,
uint8_t comms_reply_id,
uint8_t return_value)
int en50221_app_lowspeed_send_comms_reply(struct en50221_app_lowspeed *lowspeed,
uint16_t session_number,
uint8_t comms_reply_id,
uint8_t return_value)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
uint8_t data[6];
data[0] = (TAG_COMMS_REPLY >> 16) & 0xFF;
data[1] = (TAG_COMMS_REPLY >> 8) & 0xFF;
data[2] = TAG_COMMS_REPLY & 0xFF;
data[3] = 2;
data[4] = comms_reply_id;
data[5] = return_value;
return private->funcs->send_data(private->funcs->arg, session_number, data, 6);
uint8_t data[6];
data[0] = (TAG_COMMS_REPLY >> 16) & 0xFF;
data[1] = (TAG_COMMS_REPLY >> 8) & 0xFF;
data[2] = TAG_COMMS_REPLY & 0xFF;
data[3] = 2;
data[4] = comms_reply_id;
data[5] = return_value;
return lowspeed->funcs->send_data(lowspeed->funcs->arg,
session_number, data, 6);
}
int en50221_app_lowspeed_send_comms_data(en50221_app_lowspeed lowspeed,
uint16_t session_number,
uint8_t phase_id,
uint32_t tx_data_length,
uint8_t *tx_data)
int en50221_app_lowspeed_send_comms_data(struct en50221_app_lowspeed *lowspeed,
uint16_t session_number,
uint8_t phase_id,
uint32_t tx_data_length,
uint8_t * tx_data)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
uint8_t buf[10];
// the spec defines this limit
if (tx_data_length > 254) {
return -1;
}
// set up the tag
buf[0] = (TAG_COMMS_RECV_LAST >> 16) & 0xFF;
buf[1] = (TAG_COMMS_RECV_LAST >> 8) & 0xFF;
buf[2] = TAG_COMMS_RECV_LAST & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(tx_data_length+1, buf+3, 3)) < 0) {
return -1;
}
// the phase_id
buf[3+length_field_len] = phase_id;
// build the iovecs
struct iovec iov[2];
iov[0].iov_base = buf;
iov[0].iov_len = 3+length_field_len+1;
iov[1].iov_base = tx_data;
iov[1].iov_len = tx_data_length;
// create the data and send it
return private->funcs->send_datav(private->funcs->arg, session_number, iov, 2);
uint8_t buf[10];
// the spec defines this limit
if (tx_data_length > 254) {
return -1;
}
// set up the tag
buf[0] = (TAG_COMMS_RECV_LAST >> 16) & 0xFF;
buf[1] = (TAG_COMMS_RECV_LAST >> 8) & 0xFF;
buf[2] = TAG_COMMS_RECV_LAST & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(tx_data_length + 1, buf + 3, 3)) < 0) {
return -1;
}
// the phase_id
buf[3 + length_field_len] = phase_id;
// build the iovecs
struct iovec iov[2];
iov[0].iov_base = buf;
iov[0].iov_len = 3 + length_field_len + 1;
iov[1].iov_base = tx_data;
iov[1].iov_len = tx_data_length;
// create the data and send it
return lowspeed->funcs->send_datav(lowspeed->funcs->arg,
session_number, iov, 2);
}
int en50221_app_lowspeed_message(en50221_app_lowspeed lowspeed,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_lowspeed_message(struct en50221_app_lowspeed *lowspeed,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_lowspeed_private *private = (struct en50221_app_lowspeed_private *) lowspeed;
(void)resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_COMMS_COMMAND:
return en50221_app_lowspeed_parse_command(private, slot_id, session_number, data+3, data_length-3);
case TAG_COMMS_SEND_LAST:
return en50221_app_lowspeed_parse_send(private, slot_id, session_number, 1, data+3, data_length-3);
case TAG_COMMS_SEND_MORE:
return en50221_app_lowspeed_parse_send(private, slot_id, session_number, 0, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_COMMS_COMMAND:
return en50221_app_lowspeed_parse_command(lowspeed,
slot_id,
session_number,
data + 3,
data_length - 3);
case TAG_COMMS_SEND_LAST:
return en50221_app_lowspeed_parse_send(lowspeed, slot_id,
session_number, 1,
data + 3,
data_length - 3);
case TAG_COMMS_SEND_MORE:
return en50221_app_lowspeed_parse_send(lowspeed, slot_id,
session_number, 0,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
static int en50221_app_lowspeed_parse_connect_on_channel(struct en50221_app_lowspeed_command *command,
uint8_t *data,
int data_length)
uint8_t *data,
int data_length)
{
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
// check the tag
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
if (tag != TAG_CONNECTION_DESCRIPTOR) {
print(LOG_LEVEL, ERROR, 1, "Received bad CONNECT_ON_CHANNEL\n");
return -1;
}
data+=3;
data_length-=3;
// parse the descriptor-length-field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
data+=length_field_len;
data_length-=length_field_len;
// check length field
if (asn_data_length > data_length) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length < 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
// get the descriptor type
command->u.connect_on_channel.descriptor_type = data[0];
data++;
data_length--;
asn_data_length--;
// deal with the descriptor itself
switch(command->u.connect_on_channel.descriptor_type) {
case CONNECTION_DESCRIPTOR_TYPE_TELEPHONE:
{
// get the raw descriptor and validate length
struct descriptor *d = (struct descriptor*) data;
if (asn_data_length < 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length != (2 + d->len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (d->tag != dtag_dvb_telephone) {
print(LOG_LEVEL, ERROR, 1, "Received invalid telephone descriptor\n");
return -1;
}
// parse the telephone descriptor
command->u.connect_on_channel.descriptor.telephone = dvb_telephone_descriptor_codec(d);
if (command->u.connect_on_channel.descriptor.telephone == NULL) {
print(LOG_LEVEL, ERROR, 1, "Received invalid telephone descriptor\n");
return -1;
}
data += 2 + d->len;
data_length -= 2 + d->len;
break;
}
case CONNECTION_DESCRIPTOR_TYPE_CABLE:
if (asn_data_length != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
command->u.connect_on_channel.descriptor.cable_channel_id = data[0];
data++;
data_length--;
break;
default:
print(LOG_LEVEL, ERROR, 1, "Received unknown connection descriptor %02x\n",
command->u.connect_on_channel.descriptor_type);
return -1;
}
// parse the last bit
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
command->u.connect_on_channel.retry_count = data[0];
command->u.connect_on_channel.timeout = data[1];
// ok
return 0;
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
// check the tag
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
if (tag != TAG_CONNECTION_DESCRIPTOR) {
print(LOG_LEVEL, ERROR, 1,
"Received bad CONNECT_ON_CHANNEL\n");
return -1;
}
data += 3;
data_length -= 3;
// parse the descriptor-length-field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
data += length_field_len;
data_length -= length_field_len;
// check length field
if (asn_data_length > data_length) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length < 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
// get the descriptor type
command->u.connect_on_channel.descriptor_type = data[0];
data++;
data_length--;
asn_data_length--;
// deal with the descriptor itself
switch (command->u.connect_on_channel.descriptor_type) {
case CONNECTION_DESCRIPTOR_TYPE_TELEPHONE:
{
// get the raw descriptor and validate length
struct descriptor *d = (struct descriptor *) data;
if (asn_data_length < 2) {
print(LOG_LEVEL, ERROR, 1,
"Received short data\n");
return -1;
}
if (asn_data_length != (2 + d->len)) {
print(LOG_LEVEL, ERROR, 1,
"Received short data\n");
return -1;
}
if (d->tag != dtag_dvb_telephone) {
print(LOG_LEVEL, ERROR, 1,
"Received invalid telephone descriptor\n");
return -1;
}
// parse the telephone descriptor
command->u.connect_on_channel.descriptor.telephone = dvb_telephone_descriptor_codec(d);
if (command->u.connect_on_channel.descriptor.telephone == NULL) {
print(LOG_LEVEL, ERROR, 1,
"Received invalid telephone descriptor\n");
return -1;
}
data += 2 + d->len;
data_length -= 2 + d->len;
break;
}
case CONNECTION_DESCRIPTOR_TYPE_CABLE:
if (asn_data_length != 1) {
print(LOG_LEVEL, ERROR, 1,
"Received short data\n");
return -1;
}
command->u.connect_on_channel.descriptor.cable_channel_id = data[0];
data++;
data_length--;
break;
default:
print(LOG_LEVEL, ERROR, 1,
"Received unknown connection descriptor %02x\n",
command->u.connect_on_channel.descriptor_type);
return -1;
}
// parse the last bit
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
command->u.connect_on_channel.retry_count = data[0];
command->u.connect_on_channel.timeout = data[1];
// ok
return 0;
}
static int en50221_app_lowspeed_parse_command(struct en50221_app_lowspeed_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_lowspeed_parse_command(struct en50221_app_lowspeed *lowspeed,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length < 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length-length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
data+=length_field_len;
// get command id
uint8_t command_id = data[0];
data++;
asn_data_length--;
// parse the command
struct en50221_app_lowspeed_command command;
switch(command_id) {
case COMMS_COMMAND_ID_CONNECT_ON_CHANNEL:
if (en50221_app_lowspeed_parse_connect_on_channel(&command, data, asn_data_length)) {
return -1;
}
break;
case COMMS_COMMAND_ID_SET_PARAMS:
if (asn_data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
command.u.set_params.buffer_size = data[0];
command.u.set_params.timeout = data[1];
break;
case COMMS_COMMAND_ID_GET_NEXT_BUFFER:
if (asn_data_length != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
command.u.get_next_buffer.phase_id = data[0];
break;
case COMMS_COMMAND_ID_DISCONNECT_ON_CHANNEL:
case COMMS_COMMAND_ID_ENQUIRE_STATUS:
break;
default:
print(LOG_LEVEL, ERROR, 1, "Received unexpected command_id %02x\n", command_id);
return -1;
}
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_lowspeed_command_callback cb = private->command_callback;
void *cb_arg = private->command_callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, command_id, &command);
}
return 0;
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length < 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
data += length_field_len;
// get command id
uint8_t command_id = data[0];
data++;
asn_data_length--;
// parse the command
struct en50221_app_lowspeed_command command;
switch (command_id) {
case COMMS_COMMAND_ID_CONNECT_ON_CHANNEL:
if (en50221_app_lowspeed_parse_connect_on_channel
(&command, data, asn_data_length)) {
return -1;
}
break;
case COMMS_COMMAND_ID_SET_PARAMS:
if (asn_data_length != 2) {
print(LOG_LEVEL, ERROR, 1,
"Received short data\n");
return -1;
}
command.u.set_params.buffer_size = data[0];
command.u.set_params.timeout = data[1];
break;
case COMMS_COMMAND_ID_GET_NEXT_BUFFER:
if (asn_data_length != 1) {
print(LOG_LEVEL, ERROR, 1,
"Received short data\n");
return -1;
}
command.u.get_next_buffer.phase_id = data[0];
break;
case COMMS_COMMAND_ID_DISCONNECT_ON_CHANNEL:
case COMMS_COMMAND_ID_ENQUIRE_STATUS:
break;
default:
print(LOG_LEVEL, ERROR, 1,
"Received unexpected command_id %02x\n", command_id);
return -1;
}
// tell the app
pthread_mutex_lock(&lowspeed->lock);
en50221_app_lowspeed_command_callback cb = lowspeed->command_callback;
void *cb_arg = lowspeed->command_callback_arg;
pthread_mutex_unlock(&lowspeed->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, command_id,
&command);
}
return 0;
}
static int en50221_app_lowspeed_parse_send(struct en50221_app_lowspeed_private *private,
uint8_t slot_id, uint16_t session_number, int more_last,
uint8_t *data, uint32_t data_length)
static int en50221_app_lowspeed_parse_send(struct en50221_app_lowspeed *lowspeed,
uint8_t slot_id,
uint16_t session_number,
int more_last,
uint8_t *data,
uint32_t data_length)
{
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length > (data_length-length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
// skip over the length field
data += length_field_len;
// find previous session
pthread_mutex_lock(&private->lock);
struct en50221_app_lowspeed_session *cur_s = private->sessions;
while(cur_s) {
if (cur_s->session_number == session_number)
break;
cur_s=cur_s->next;
}
// more data is still to come
if (!more_last) {
// if there was no previous session, create one
if (cur_s == NULL) {
cur_s = malloc(sizeof(struct en50221_app_lowspeed_session));
if (cur_s == NULL) {
print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
pthread_mutex_unlock(&private->lock);
return -1;
}
cur_s->session_number = session_number;
cur_s->block_chain = NULL;
cur_s->block_length = 0;
cur_s->next = private->sessions;
private->sessions = cur_s;
}
// append the data
uint8_t *new_data = realloc(cur_s->block_chain, cur_s->block_length + asn_data_length);
if (new_data == NULL) {
print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
pthread_mutex_unlock(&private->lock);
return -1;
}
memcpy(new_data + cur_s->block_length, data, asn_data_length);
cur_s->block_chain = new_data;
cur_s->block_length += asn_data_length;
// done
pthread_mutex_unlock(&private->lock);
return 0;
}
// we hit the last of a possible chain of fragments
int do_free = 0;
if (cur_s != NULL) {
// we have a preceding fragment - need to append
uint8_t *new_data = realloc(cur_s->block_chain, cur_s->block_length + asn_data_length);
if (new_data == NULL) {
print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
pthread_mutex_unlock(&private->lock);
return -1;
}
memcpy(new_data + cur_s->block_length, data, asn_data_length);
asn_data_length = cur_s->block_length + asn_data_length;
data = new_data;
cur_s->block_chain = NULL;
cur_s->block_length = 0;
do_free = 1;
}
// check the reassembled data length
if (asn_data_length < 1) {
pthread_mutex_unlock(&private->lock);
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
if (do_free) free(data);
return -1;
}
// now, parse the data
uint8_t phase_id = data[0];
// tell the app
en50221_app_lowspeed_send_callback cb = private->send_callback;
void *cb_arg = private->send_callback_arg;
pthread_mutex_unlock(&private->lock);
int cbstatus = 0;
if (cb) {
cbstatus = cb(cb_arg, slot_id, session_number, phase_id, data+1, asn_data_length-1);
}
// done
if (do_free) free(data);
return cbstatus;
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
// skip over the length field
data += length_field_len;
// find previous session
pthread_mutex_lock(&lowspeed->lock);
struct en50221_app_lowspeed_session *cur_s = lowspeed->sessions;
while (cur_s) {
if (cur_s->session_number == session_number)
break;
cur_s = cur_s->next;
}
// more data is still to come
if (!more_last) {
// if there was no previous session, create one
if (cur_s == NULL) {
cur_s = malloc(sizeof(struct en50221_app_lowspeed_session));
if (cur_s == NULL) {
print(LOG_LEVEL, ERROR, 1,
"Ran out of memory\n");
pthread_mutex_unlock(&lowspeed->lock);
return -1;
}
cur_s->session_number = session_number;
cur_s->block_chain = NULL;
cur_s->block_length = 0;
cur_s->next = lowspeed->sessions;
lowspeed->sessions = cur_s;
}
// append the data
uint8_t *new_data = realloc(cur_s->block_chain,
cur_s->block_length + asn_data_length);
if (new_data == NULL) {
print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
pthread_mutex_unlock(&lowspeed->lock);
return -1;
}
memcpy(new_data + cur_s->block_length, data, asn_data_length);
cur_s->block_chain = new_data;
cur_s->block_length += asn_data_length;
// done
pthread_mutex_unlock(&lowspeed->lock);
return 0;
}
// we hit the last of a possible chain of fragments
int do_free = 0;
if (cur_s != NULL) {
// we have a preceding fragment - need to append
uint8_t *new_data = realloc(cur_s->block_chain,
cur_s->block_length + asn_data_length);
if (new_data == NULL) {
print(LOG_LEVEL, ERROR, 1, "Ran out of memory\n");
pthread_mutex_unlock(&lowspeed->lock);
return -1;
}
memcpy(new_data + cur_s->block_length, data, asn_data_length);
asn_data_length = cur_s->block_length + asn_data_length;
data = new_data;
cur_s->block_chain = NULL;
cur_s->block_length = 0;
do_free = 1;
}
// check the reassembled data length
if (asn_data_length < 1) {
pthread_mutex_unlock(&lowspeed->lock);
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
if (do_free)
free(data);
return -1;
}
// now, parse the data
uint8_t phase_id = data[0];
// tell the app
en50221_app_lowspeed_send_callback cb = lowspeed->send_callback;
void *cb_arg = lowspeed->send_callback_arg;
pthread_mutex_unlock(&lowspeed->lock);
int cbstatus = 0;
if (cb) {
cbstatus =
cb(cb_arg, slot_id, session_number, phase_id, data + 1, asn_data_length - 1);
}
// done
if (do_free)
free(data);
return cbstatus;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_LOWSPEED_H__
#define __EN50221_APPLICATION_LOWSPEED_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -57,26 +56,26 @@ extern "C"
* Structure holding information on a received comms command.
*/
struct en50221_app_lowspeed_command {
union {
struct {
uint8_t descriptor_type; // CONNECTION_DESCRIPTOR_TYPE_*
uint8_t retry_count;
uint8_t timeout;
union {
struct dvb_telephone_descriptor *telephone;
uint8_t cable_channel_id;
} descriptor;
} connect_on_channel;
struct {
uint8_t buffer_size;
uint8_t timeout;
} set_params;
struct {
uint8_t phase_id;
} get_next_buffer;
} u;
union {
struct {
uint8_t descriptor_type; // CONNECTION_DESCRIPTOR_TYPE_*
uint8_t retry_count;
uint8_t timeout;
union {
struct dvb_telephone_descriptor *telephone;
uint8_t cable_channel_id;
} descriptor;
} connect_on_channel;
struct {
uint8_t buffer_size;
uint8_t timeout;
} set_params;
struct {
uint8_t phase_id;
} get_next_buffer;
} u;
};
/**
@ -89,9 +88,11 @@ struct en50221_app_lowspeed_command {
* @param command Pointer to a lowspeed command structure containing the command data.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_lowspeed_command_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t command_id,
struct en50221_app_lowspeed_command *command);
typedef int (*en50221_app_lowspeed_command_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t command_id,
struct en50221_app_lowspeed_command *command);
/**
* Type definition for send - called when we receive data to send. The block can be segmented into
@ -105,13 +106,17 @@ typedef int (*en50221_app_lowspeed_command_callback)(void *arg, uint8_t slot_id,
* @param length Number of bytes.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_lowspeed_send_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t phase_id, uint8_t *data, uint32_t length);
typedef int (*en50221_app_lowspeed_send_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t phase_id,
uint8_t *data,
uint32_t length);
/**
* Opaque type representing a lowspeed resource.
*/
typedef void *en50221_app_lowspeed;
struct en50221_app_lowspeed;
/**
* Create an instance of the lowspeed resource.
@ -119,14 +124,15 @@ typedef void *en50221_app_lowspeed;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_lowspeed en50221_app_lowspeed_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_lowspeed *
en50221_app_lowspeed_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the lowspeed resource.
*
* @param lowspeed Instance to destroy.
*/
extern void en50221_app_lowspeed_destroy(en50221_app_lowspeed lowspeed);
extern void en50221_app_lowspeed_destroy(struct en50221_app_lowspeed *lowspeed);
/**
* Informs the lowspeed object that a session to it has been closed - cleans up internal state.
@ -134,7 +140,8 @@ extern void en50221_app_lowspeed_destroy(en50221_app_lowspeed lowspeed);
* @param lowspeed lowspeed resource instance.
* @param session_number The session concerned.
*/
extern void en50221_app_lowspeed_clear_session(en50221_app_lowspeed lowspeed, uint16_t session_number);
extern void en50221_app_lowspeed_clear_session(struct en50221_app_lowspeed *lowspeed,
uint16_t session_number);
/**
* Register the callback for when we receive a comms command.
@ -143,8 +150,9 @@ extern void en50221_app_lowspeed_clear_session(en50221_app_lowspeed lowspeed, ui
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_lowspeed_register_command_callback(en50221_app_lowspeed lowspeed,
en50221_app_lowspeed_command_callback callback, void *arg);
extern void en50221_app_lowspeed_register_command_callback(struct en50221_app_lowspeed *lowspeed,
en50221_app_lowspeed_command_callback callback,
void *arg);
/**
* Register the callback for when we receive data to send.
@ -153,8 +161,9 @@ extern void en50221_app_lowspeed_register_command_callback(en50221_app_lowspeed
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_lowspeed_register_send_callback(en50221_app_lowspeed lowspeed,
en50221_app_lowspeed_send_callback callback, void *arg);
extern void en50221_app_lowspeed_register_send_callback(struct en50221_app_lowspeed *lowspeed,
en50221_app_lowspeed_send_callback callback,
void *arg);
/**
* Send a comms reply to the CAM.
@ -165,10 +174,10 @@ extern void en50221_app_lowspeed_register_send_callback(en50221_app_lowspeed low
* @param return_value Comms reply specific value.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_lowspeed_send_comms_reply(en50221_app_lowspeed lowspeed,
uint16_t session_number,
uint8_t comms_reply_id,
uint8_t return_value);
extern int en50221_app_lowspeed_send_comms_reply(struct en50221_app_lowspeed *lowspeed,
uint16_t session_number,
uint8_t comms_reply_id,
uint8_t return_value);
/**
* Send received data to the CAM.
@ -180,11 +189,11 @@ extern int en50221_app_lowspeed_send_comms_reply(en50221_app_lowspeed lowspeed,
* @param tx_data Data.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_lowspeed_send_comms_data(en50221_app_lowspeed lowspeed,
uint16_t session_number,
uint8_t phase_id,
uint32_t tx_data_length,
uint8_t *tx_data);
extern int en50221_app_lowspeed_send_comms_data(struct en50221_app_lowspeed *lowspeed,
uint16_t session_number,
uint8_t phase_id,
uint32_t tx_data_length,
uint8_t * tx_data);
/**
* Pass data received for this resource into it for parsing.
@ -197,14 +206,14 @@ extern int en50221_app_lowspeed_send_comms_data(en50221_app_lowspeed lowspeed,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_lowspeed_message(en50221_app_lowspeed lowspeed,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_lowspeed_message(struct en50221_app_lowspeed *lowspeed,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_mmi_H__
#define __EN50221_APPLICATION_mmi_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -88,48 +87,48 @@ extern "C"
* A pixel depth as supplied with display_reply details
*/
struct en50221_app_mmi_pixel_depth {
uint8_t display_depth;
uint8_t pixels_per_byte;
uint8_t region_overhead;
uint8_t display_depth;
uint8_t pixels_per_byte;
uint8_t region_overhead;
};
/**
* Details returned with a display_reply
*/
struct en502221_app_mmi_display_reply_details {
union {
struct {
uint16_t width;
uint16_t height;
uint8_t aspect_ratio;
uint8_t gfx_relation_to_video; /* one of MMI_GFX_VIDEO_RELATION_* */
uint8_t multiple_depths;
uint16_t display_bytes;
uint8_t composition_buffer_bytes;
uint8_t object_cache_bytes;
uint8_t num_pixel_depths;
struct en50221_app_mmi_pixel_depth *pixel_depths;
} gfx; /* MMI_DISPLAY_REPLY_ID_LIST_OVERLAY_GFX_CHARACTERISTICS or
MMI_DISPLAY_REPLY_ID_LIST_FULLSCREEN_GFX_CHARACTERISTICS */
struct {
uint32_t table_length;
uint8_t *table;
} char_table; /* MMI_DISPLAY_REPLY_ID_LIST_DISPLAY_CHAR_TABLES or
MMI_DISPLAY_REPLY_ID_LIST_INPUT_CHAR_TABLES */
struct {
uint8_t mmi_mode; /* one of the MMI_MODE_* values */
} mode_ack; /* for MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK */
} u;
struct en50221_app_mmi_display_reply_details {
union {
struct {
uint16_t width;
uint16_t height;
uint8_t aspect_ratio;
uint8_t gfx_relation_to_video; /* one of MMI_GFX_VIDEO_RELATION_* */
uint8_t multiple_depths;
uint16_t display_bytes;
uint8_t composition_buffer_bytes;
uint8_t object_cache_bytes;
uint8_t num_pixel_depths;
struct en50221_app_mmi_pixel_depth *pixel_depths;
} gfx; /* MMI_DISPLAY_REPLY_ID_LIST_OVERLAY_GFX_CHARACTERISTICS or
MMI_DISPLAY_REPLY_ID_LIST_FULLSCREEN_GFX_CHARACTERISTICS */
struct {
uint32_t table_length;
uint8_t *table;
} char_table; /* MMI_DISPLAY_REPLY_ID_LIST_DISPLAY_CHAR_TABLES or
MMI_DISPLAY_REPLY_ID_LIST_INPUT_CHAR_TABLES */
struct {
uint8_t mmi_mode; /* one of the MMI_MODE_* values */
} mode_ack; /* for MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK */
} u;
};
/**
* Pointer to a text string.
*/
struct en50221_app_mmi_text {
uint8_t *text;
uint32_t text_length;
uint8_t *text;
uint32_t text_length;
};
/**
@ -142,8 +141,11 @@ struct en50221_app_mmi_text {
* @param delay Delay supplied with MMI_CLOSE_MMI_CMD_ID_DELAY.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_close_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t cmd_id, uint8_t delay);
typedef int (*en50221_app_mmi_close_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t cmd_id,
uint8_t delay);
/**
* Type definition for display_control callback.
@ -155,8 +157,11 @@ typedef int (*en50221_app_mmi_close_callback)(void *arg, uint8_t slot_id, uint16
* @param delay One of the MMI_MODE_* values.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_display_control_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t cmd_id, uint8_t mmi_mode);
typedef int (*en50221_app_mmi_display_control_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t cmd_id,
uint8_t mmi_mode);
/**
* Type definition for keypad_control callback.
@ -169,8 +174,12 @@ typedef int (*en50221_app_mmi_display_control_callback)(void *arg, uint8_t slot_
* @param key_codes_count Number of key codes.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_keypad_control_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t cmd_id, uint8_t *key_codes, uint32_t key_codes_count);
typedef int (*en50221_app_mmi_keypad_control_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t cmd_id,
uint8_t *key_codes,
uint32_t key_codes_count);
/**
* Type definition for subtitle_segment callback.
@ -182,8 +191,11 @@ typedef int (*en50221_app_mmi_keypad_control_callback)(void *arg, uint8_t slot_i
* @param segment_size Size of segment data.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_subtitle_segment_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t *segment, uint32_t segment_size);
typedef int (*en50221_app_mmi_subtitle_segment_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t *segment,
uint32_t segment_size);
/**
* Type definition for scene_end_mark callback.
@ -197,9 +209,13 @@ typedef int (*en50221_app_mmi_subtitle_segment_callback)(void *arg, uint8_t slot
* @param scene_tag
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_scene_end_mark_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
uint8_t send_scene_done, uint8_t scene_tag);
typedef int (*en50221_app_mmi_scene_end_mark_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t decoder_continue_flag,
uint8_t scene_reveal_flag,
uint8_t send_scene_done,
uint8_t scene_tag);
/**
* Type definition for scene_control callback.
@ -212,9 +228,12 @@ typedef int (*en50221_app_mmi_scene_end_mark_callback)(void *arg, uint8_t slot_i
* @param scene_tag
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_scene_control_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t decoder_continue_flag, uint8_t scene_reveal_flag,
uint8_t scene_tag);
typedef int (*en50221_app_mmi_scene_control_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t decoder_continue_flag,
uint8_t scene_reveal_flag,
uint8_t scene_tag);
/**
* Type definition for subtitle_download callback.
@ -226,8 +245,11 @@ typedef int (*en50221_app_mmi_scene_control_callback)(void *arg, uint8_t slot_id
* @param segment_size Size of segment data.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_subtitle_download_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t *segment, uint32_t segment_size);
typedef int (*en50221_app_mmi_subtitle_download_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t *segment,
uint32_t segment_size);
/**
* Type definition for flush_download callback.
@ -237,7 +259,9 @@ typedef int (*en50221_app_mmi_subtitle_download_callback)(void *arg, uint8_t slo
* @param session_number Session number concerned.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_flush_download_callback)(void *arg, uint8_t slot_id, uint16_t session_number);
typedef int (*en50221_app_mmi_flush_download_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number);
/**
* Type definition for enq callback.
@ -251,9 +275,13 @@ typedef int (*en50221_app_mmi_flush_download_callback)(void *arg, uint8_t slot_i
* @param text_size Size of text data.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_enq_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t blind_answer, uint8_t expected_answer_length,
uint8_t *text, uint32_t text_size);
typedef int (*en50221_app_mmi_enq_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t blind_answer,
uint8_t expected_answer_length,
uint8_t * text,
uint32_t text_size);
/**
* Type definition for menu callback.
@ -270,12 +298,16 @@ typedef int (*en50221_app_mmi_enq_callback)(void *arg, uint8_t slot_id, uint16_t
* @param items_raw If nonstandard items were supplied, pointer to their data.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_menu_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
struct en50221_app_mmi_text *title,
struct en50221_app_mmi_text *sub_title,
struct en50221_app_mmi_text *bottom,
uint32_t item_count, struct en50221_app_mmi_text *items,
uint32_t item_raw_length, uint8_t *items_raw);
typedef int (*en50221_app_mmi_menu_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
struct en50221_app_mmi_text *title,
struct en50221_app_mmi_text *sub_title,
struct en50221_app_mmi_text *bottom,
uint32_t item_count,
struct en50221_app_mmi_text *items,
uint32_t item_raw_length,
uint8_t *items_raw);
/**
* Type definition for list callback.
@ -292,17 +324,21 @@ typedef int (*en50221_app_mmi_menu_callback)(void *arg, uint8_t slot_id, uint16_
* @param items_raw If nonstandard items were supplied, pointer to their data.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_mmi_list_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
struct en50221_app_mmi_text *title,
struct en50221_app_mmi_text *sub_title,
struct en50221_app_mmi_text *bottom,
uint32_t item_count, struct en50221_app_mmi_text *items,
uint32_t item_raw_length, uint8_t *items_raw);
typedef int (*en50221_app_mmi_list_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
struct en50221_app_mmi_text *title,
struct en50221_app_mmi_text *sub_title,
struct en50221_app_mmi_text *bottom,
uint32_t item_count,
struct en50221_app_mmi_text *items,
uint32_t item_raw_length,
uint8_t *items_raw);
/**
* Opaque type representing a mmi resource.
*/
typedef void *en50221_app_mmi;
struct en50221_app_mmi;
/**
* Create an instance of the mmi resource.
@ -310,14 +346,14 @@ typedef void *en50221_app_mmi;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_mmi en50221_app_mmi_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_mmi *en50221_app_mmi_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the mmi resource.
*
* @param mmi Instance to destroy.
*/
extern void en50221_app_mmi_destroy(en50221_app_mmi mmi);
extern void en50221_app_mmi_destroy(struct en50221_app_mmi *mmi);
/**
* Informs the mmi object that a session to it has been closed - cleans up internal state.
@ -325,7 +361,8 @@ extern void en50221_app_mmi_destroy(en50221_app_mmi mmi);
* @param mmi mmi resource instance.
* @param session_number The session concerned.
*/
extern void en50221_app_mmi_clear_session(en50221_app_mmi mmi, uint16_t session_number);
extern void en50221_app_mmi_clear_session(struct en50221_app_mmi *mmi,
uint16_t session_number);
/**
* Register the callback for when we receive an mmi_close request.
@ -334,8 +371,9 @@ extern void en50221_app_mmi_clear_session(en50221_app_mmi mmi, uint16_t session_
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_close_callback(en50221_app_mmi mmi,
en50221_app_mmi_close_callback callback, void *arg);
extern void en50221_app_mmi_register_close_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_close_callback callback,
void *arg);
/**
* Register the callback for when we receive a display control request.
@ -344,8 +382,9 @@ extern void en50221_app_mmi_register_close_callback(en50221_app_mmi mmi,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_display_control_callback(en50221_app_mmi mmi,
en50221_app_mmi_display_control_callback callback, void *arg);
extern void en50221_app_mmi_register_display_control_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_display_control_callback callback,
void *arg);
/**
* Register the callback for when we receive a keypad control request.
@ -354,8 +393,9 @@ extern void en50221_app_mmi_register_display_control_callback(en50221_app_mmi mm
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_keypad_control_callback(en50221_app_mmi mmi,
en50221_app_mmi_keypad_control_callback callback, void *arg);
extern void en50221_app_mmi_register_keypad_control_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_keypad_control_callback callback,
void *arg);
/**
* Register the callback for when we receive a subtitle segment request.
@ -364,8 +404,9 @@ extern void en50221_app_mmi_register_keypad_control_callback(en50221_app_mmi mmi
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_subtitle_segment_callback(en50221_app_mmi mmi,
en50221_app_mmi_subtitle_segment_callback callback, void *arg);
extern void en50221_app_mmi_register_subtitle_segment_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_subtitle_segment_callback callback,
void *arg);
/**
* Register the callback for when we receive a scene end mark request.
@ -374,8 +415,9 @@ extern void en50221_app_mmi_register_subtitle_segment_callback(en50221_app_mmi m
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_scene_end_mark_callback(en50221_app_mmi mmi,
en50221_app_mmi_scene_end_mark_callback callback, void *arg);
extern void en50221_app_mmi_register_scene_end_mark_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_scene_end_mark_callback callback,
void *arg);
/**
* Register the callback for when we receive a scene control request.
@ -384,8 +426,9 @@ extern void en50221_app_mmi_register_scene_end_mark_callback(en50221_app_mmi mmi
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_scene_control_callback(en50221_app_mmi mmi,
en50221_app_mmi_scene_control_callback callback, void *arg);
extern void en50221_app_mmi_register_scene_control_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_scene_control_callback callback,
void *arg);
/**
* Register the callback for when we receive a subtitle download request.
@ -394,8 +437,9 @@ extern void en50221_app_mmi_register_scene_control_callback(en50221_app_mmi mmi,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_subtitle_download_callback(en50221_app_mmi mmi,
en50221_app_mmi_subtitle_download_callback callback, void *arg);
extern void en50221_app_mmi_register_subtitle_download_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_subtitle_download_callback callback,
void *arg);
/**
* Register the callback for when we receive a flush download request.
@ -404,8 +448,9 @@ extern void en50221_app_mmi_register_subtitle_download_callback(en50221_app_mmi
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_flush_download_callback(en50221_app_mmi mmi,
en50221_app_mmi_flush_download_callback callback, void *arg);
extern void en50221_app_mmi_register_flush_download_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_flush_download_callback callback,
void *arg);
/**
* Register the callback for when we receive an enq request.
@ -414,8 +459,9 @@ extern void en50221_app_mmi_register_flush_download_callback(en50221_app_mmi mmi
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_enq_callback(en50221_app_mmi mmi,
en50221_app_mmi_enq_callback callback, void *arg);
extern void en50221_app_mmi_register_enq_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_enq_callback callback,
void *arg);
/**
* Register the callback for when we receive a menu request.
@ -424,8 +470,9 @@ extern void en50221_app_mmi_register_enq_callback(en50221_app_mmi mmi,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_menu_callback(en50221_app_mmi mmi,
en50221_app_mmi_menu_callback callback, void *arg);
extern void en50221_app_mmi_register_menu_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_menu_callback callback,
void *arg);
/**
* Register the callback for when we receive a list request.
@ -434,8 +481,9 @@ extern void en50221_app_mmi_register_menu_callback(en50221_app_mmi mmi,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_mmi_register_list_callback(en50221_app_mmi mmi,
en50221_app_mmi_list_callback callback, void *arg);
extern void en50221_app_mmi_register_list_callback(struct en50221_app_mmi *mmi,
en50221_app_mmi_list_callback callback,
void *arg);
/**
* Send an mmi_close to the cam.
@ -446,10 +494,9 @@ extern void en50221_app_mmi_register_list_callback(en50221_app_mmi mmi,
* @param delay Delay to use if MMI_CLOSE_MMI_CMD_ID_DELAY specified.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_close(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t cmd_id,
uint8_t delay);
extern int en50221_app_mmi_close(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t cmd_id, uint8_t delay);
/**
* Send a display_reply to the cam.
@ -460,10 +507,10 @@ extern int en50221_app_mmi_close(en50221_app_mmi mmi,
* @param details The details of the reply - can be NULL if the chosen reply_id does not need it.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_display_reply(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t reply_id,
struct en502221_app_mmi_display_reply_details *details);
extern int en50221_app_mmi_display_reply(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t reply_id,
struct en50221_app_mmi_display_reply_details *details);
/**
* Send a keypress to the cam.
@ -473,9 +520,9 @@ extern int en50221_app_mmi_display_reply(en50221_app_mmi mmi,
* @param keycode The keycode.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_keypress(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t keycode);
extern int en50221_app_mmi_keypress(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t keycode);
/**
* Send a display message to the cam.
@ -485,9 +532,9 @@ extern int en50221_app_mmi_keypress(en50221_app_mmi mmi,
* @param display_message_id One of the MMI_DISPLAY_MESSAGE_ID_* values.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_display_message(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t display_message_id);
extern int en50221_app_mmi_display_message(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t display_message_id);
/**
* Send a scene done message to the cam.
@ -499,11 +546,11 @@ extern int en50221_app_mmi_display_message(en50221_app_mmi mmi,
* @param scene_tag Scene tag this responds to.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_scene_done(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t decoder_continue,
uint8_t scene_reveal,
uint8_t scene_tag);
extern int en50221_app_mmi_scene_done(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t decoder_continue,
uint8_t scene_reveal,
uint8_t scene_tag);
/**
* Send a download reply to the cam.
@ -514,10 +561,10 @@ extern int en50221_app_mmi_scene_done(en50221_app_mmi mmi,
* @param download_reply_id One of the MMI_DOWNLOAD_REPLY_ID_* values.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_download_reply(en50221_app_mmi mmi,
uint16_t session_number,
uint16_t object_id,
uint8_t download_reply_id);
extern int en50221_app_mmi_download_reply(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint16_t object_id,
uint8_t download_reply_id);
/**
* Send an answ to the cam.
@ -529,11 +576,11 @@ extern int en50221_app_mmi_download_reply(en50221_app_mmi mmi,
* @param text_count Length of text.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_answ(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t answ_id,
uint8_t *text,
uint32_t text_count);
extern int en50221_app_mmi_answ(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t answ_id,
uint8_t * text,
uint32_t text_count);
/**
* Send a menu answ to the cam.
@ -543,9 +590,9 @@ extern int en50221_app_mmi_answ(en50221_app_mmi mmi,
* @param choice_ref Option chosen by user (0=>canceled).
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_menu_answ(en50221_app_mmi mmi,
uint16_t session_number,
uint8_t choice_ref);
extern int en50221_app_mmi_menu_answ(struct en50221_app_mmi *mmi,
uint16_t session_number,
uint8_t choice_ref);
/**
* Pass data received for this resource into it for parsing.
@ -558,14 +605,14 @@ extern int en50221_app_mmi_menu_answ(en50221_app_mmi mmi,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_mmi_message(en50221_app_mmi mmi,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_mmi_message(struct en50221_app_mmi *mmi,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -29,266 +29,279 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_rm_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_rm {
struct en50221_app_send_functions *funcs;
en50221_app_rm_enq_callback enqcallback;
void *enqcallback_arg;
en50221_app_rm_enq_callback enqcallback;
void *enqcallback_arg;
en50221_app_rm_reply_callback replycallback;
void *replycallback_arg;
en50221_app_rm_reply_callback replycallback;
void *replycallback_arg;
en50221_app_rm_changed_callback changedcallback;
void *changedcallback_arg;
en50221_app_rm_changed_callback changedcallback;
void *changedcallback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_rm_parse_profile_enq(struct en50221_app_rm_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_rm_parse_profile_reply(struct en50221_app_rm_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_rm_parse_profile_change(struct en50221_app_rm_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
en50221_app_rm en50221_app_rm_create(struct en50221_app_send_functions *funcs)
static int en50221_app_rm_parse_profile_enq(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
static int en50221_app_rm_parse_profile_reply(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
static int en50221_app_rm_parse_profile_change(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
struct en50221_app_rm *en50221_app_rm_create(struct
en50221_app_send_functions
*funcs)
{
struct en50221_app_rm_private *private = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_rm_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->enqcallback = NULL;
private->replycallback = NULL;
private->changedcallback = NULL;
pthread_mutex_init(&private->lock, NULL);
// done
return private;
struct en50221_app_rm *rm = NULL;
// create structure and set it up
rm = malloc(sizeof(struct en50221_app_rm));
if (rm == NULL) {
return NULL;
}
rm->funcs = funcs;
rm->enqcallback = NULL;
rm->replycallback = NULL;
rm->changedcallback = NULL;
pthread_mutex_init(&rm->lock, NULL);
// done
return rm;
}
void en50221_app_rm_destroy(en50221_app_rm rm)
void en50221_app_rm_destroy(struct en50221_app_rm *rm)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&rm->lock);
free(rm);
}
void en50221_app_rm_register_enq_callback(en50221_app_rm rm,
en50221_app_rm_enq_callback callback, void *arg)
void en50221_app_rm_register_enq_callback(struct en50221_app_rm *rm,
en50221_app_rm_enq_callback
callback, void *arg)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
pthread_mutex_lock(&private->lock);
private->enqcallback = callback;
private->enqcallback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&rm->lock);
rm->enqcallback = callback;
rm->enqcallback_arg = arg;
pthread_mutex_unlock(&rm->lock);
}
void en50221_app_rm_register_reply_callback(en50221_app_rm rm,
en50221_app_rm_reply_callback callback, void *arg)
void en50221_app_rm_register_reply_callback(struct en50221_app_rm *rm,
en50221_app_rm_reply_callback
callback, void *arg)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
pthread_mutex_lock(&private->lock);
private->replycallback = callback;
private->replycallback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&rm->lock);
rm->replycallback = callback;
rm->replycallback_arg = arg;
pthread_mutex_unlock(&rm->lock);
}
void en50221_app_rm_register_changed_callback(en50221_app_rm rm,
en50221_app_rm_changed_callback callback, void *arg)
void en50221_app_rm_register_changed_callback(struct en50221_app_rm *rm,
en50221_app_rm_changed_callback
callback, void *arg)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
pthread_mutex_lock(&private->lock);
private->changedcallback = callback;
private->changedcallback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&rm->lock);
rm->changedcallback = callback;
rm->changedcallback_arg = arg;
pthread_mutex_unlock(&rm->lock);
}
int en50221_app_rm_enq(en50221_app_rm rm, uint16_t session_number)
int en50221_app_rm_enq(struct en50221_app_rm *rm, uint16_t session_number)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
uint8_t buf[4];
uint8_t buf[4];
// set up the tag
buf[0] = (TAG_PROFILE_ENQUIRY >> 16) & 0xFF;
buf[1] = (TAG_PROFILE_ENQUIRY >> 8) & 0xFF;
buf[2] = TAG_PROFILE_ENQUIRY & 0xFF;
buf[3] = 0;
// set up the tag
buf[0] = (TAG_PROFILE_ENQUIRY >> 16) & 0xFF;
buf[1] = (TAG_PROFILE_ENQUIRY >> 8) & 0xFF;
buf[2] = TAG_PROFILE_ENQUIRY & 0xFF;
buf[3] = 0;
// create the data and send it
return private->funcs->send_data(private->funcs->arg, session_number, buf, 4);
// create the data and send it
return rm->funcs->send_data(rm->funcs->arg, session_number, buf, 4);
}
int en50221_app_rm_reply(en50221_app_rm rm, uint16_t session_number,
uint32_t resource_id_count,
uint32_t *resource_ids)
int en50221_app_rm_reply(struct en50221_app_rm *rm,
uint16_t session_number,
uint32_t resource_id_count,
uint32_t * resource_ids)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
uint8_t buf[10];
// set up the tag
buf[0] = (TAG_PROFILE >> 16) & 0xFF;
buf[1] = (TAG_PROFILE >> 8) & 0xFF;
buf[2] = TAG_PROFILE & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(resource_id_count*4, buf+3, 3)) < 0) {
return -1;
}
// copy the data and byteswap it
uint32_t *copy_resource_ids = alloca(4*resource_id_count);
if (copy_resource_ids == NULL) {
return -1;
}
uint8_t *data = (uint8_t*) copy_resource_ids;
memcpy(data, resource_ids, resource_id_count*4);
uint32_t i;
for(i=0; i<resource_id_count; i++) {
bswap32(data);
data+=4;
}
// build the iovecs
struct iovec iov[2];
iov[0].iov_base = buf;
iov[0].iov_len = 3+length_field_len;
iov[1].iov_base = (uint8_t*) copy_resource_ids;
iov[1].iov_len = resource_id_count * 4;
// create the data and send it
return private->funcs->send_datav(private->funcs->arg, session_number, iov, 2);
uint8_t buf[10];
// set up the tag
buf[0] = (TAG_PROFILE >> 16) & 0xFF;
buf[1] = (TAG_PROFILE >> 8) & 0xFF;
buf[2] = TAG_PROFILE & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(resource_id_count * 4, buf + 3, 3)) < 0) {
return -1;
}
// copy the data and byteswap it
uint32_t *copy_resource_ids = alloca(4 * resource_id_count);
if (copy_resource_ids == NULL) {
return -1;
}
uint8_t *data = (uint8_t *) copy_resource_ids;
memcpy(data, resource_ids, resource_id_count * 4);
uint32_t i;
for (i = 0; i < resource_id_count; i++) {
bswap32(data);
data += 4;
}
// build the iovecs
struct iovec iov[2];
iov[0].iov_base = buf;
iov[0].iov_len = 3 + length_field_len;
iov[1].iov_base = (uint8_t *) copy_resource_ids;
iov[1].iov_len = resource_id_count * 4;
// create the data and send it
return rm->funcs->send_datav(rm->funcs->arg, session_number, iov, 2);
}
int en50221_app_rm_changed(en50221_app_rm rm, uint16_t session_number)
int en50221_app_rm_changed(struct en50221_app_rm *rm,
uint16_t session_number)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
uint8_t buf[4];
uint8_t buf[4];
// set up the tag
buf[0] = (TAG_PROFILE_CHANGE >> 16) & 0xFF;
buf[1] = (TAG_PROFILE_CHANGE >> 8) & 0xFF;
buf[2] = TAG_PROFILE_CHANGE & 0xFF;
buf[3] = 0;
// set up the tag
buf[0] = (TAG_PROFILE_CHANGE >> 16) & 0xFF;
buf[1] = (TAG_PROFILE_CHANGE >> 8) & 0xFF;
buf[2] = TAG_PROFILE_CHANGE & 0xFF;
buf[3] = 0;
// create the data and send it
return private->funcs->send_data(private->funcs->arg, session_number, buf, 4);
// create the data and send it
return rm->funcs->send_data(rm->funcs->arg, session_number, buf, 4);
}
int en50221_app_rm_message(en50221_app_rm rm,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_rm_message(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_rm_private *private = (struct en50221_app_rm_private *) rm;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
// dispatch it
switch(tag)
{
case TAG_PROFILE_ENQUIRY:
return en50221_app_rm_parse_profile_enq(private, slot_id, session_number, data+3, data_length-3);
case TAG_PROFILE:
return en50221_app_rm_parse_profile_reply(private, slot_id, session_number, data+3, data_length-3);
case TAG_PROFILE_CHANGE:
return en50221_app_rm_parse_profile_change(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
// dispatch it
switch (tag) {
case TAG_PROFILE_ENQUIRY:
return en50221_app_rm_parse_profile_enq(rm, slot_id,
session_number,
data + 3,
data_length - 3);
case TAG_PROFILE:
return en50221_app_rm_parse_profile_reply(rm, slot_id,
session_number,
data + 3,
data_length - 3);
case TAG_PROFILE_CHANGE:
return en50221_app_rm_parse_profile_change(rm, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
static int en50221_app_rm_parse_profile_enq(struct en50221_app_rm_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_rm_parse_profile_enq(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
(void)data;
(void)data_length;
pthread_mutex_lock(&private->lock);
en50221_app_rm_enq_callback cb = private->enqcallback;
void *cb_arg = private->enqcallback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number);
}
return 0;
(void) data;
(void) data_length;
pthread_mutex_lock(&rm->lock);
en50221_app_rm_enq_callback cb = rm->enqcallback;
void *cb_arg = rm->enqcallback_arg;
pthread_mutex_unlock(&rm->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number);
}
return 0;
}
static int en50221_app_rm_parse_profile_reply(struct en50221_app_rm_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_rm_parse_profile_reply(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length > (data_length-length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t resources_count = asn_data_length / 4;
uint32_t *resource_ids = (uint32_t*) (data+length_field_len);
data += length_field_len;
// byteswap it
uint32_t i;
for(i=0; i< resources_count; i++) {
bswap32(data);
data+=4;
}
// inform observer
pthread_mutex_lock(&private->lock);
en50221_app_rm_reply_callback cb = private->replycallback;
void *cb_arg = private->replycallback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, resources_count, resource_ids);
}
return 0;
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t resources_count = asn_data_length / 4;
uint32_t *resource_ids = (uint32_t *) (data + length_field_len);
data += length_field_len;
// byteswap it
uint32_t i;
for (i = 0; i < resources_count; i++) {
bswap32(data);
data += 4;
}
// inform observer
pthread_mutex_lock(&rm->lock);
en50221_app_rm_reply_callback cb = rm->replycallback;
void *cb_arg = rm->replycallback_arg;
pthread_mutex_unlock(&rm->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, resources_count, resource_ids);
}
return 0;
}
static int en50221_app_rm_parse_profile_change(struct en50221_app_rm_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_rm_parse_profile_change(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
(void)data;
(void)data_length;
pthread_mutex_lock(&private->lock);
en50221_app_rm_changed_callback cb = private->changedcallback;
void *cb_arg = private->changedcallback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number);
}
return 0;
(void) data;
(void) data_length;
pthread_mutex_lock(&rm->lock);
en50221_app_rm_changed_callback cb = rm->changedcallback;
void *cb_arg = rm->changedcallback_arg;
pthread_mutex_unlock(&rm->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_RM_H__
#define __EN50221_APPLICATION_RM_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -44,7 +43,9 @@ extern "C"
* @param session_number Session number concerned.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_rm_enq_callback)(void *arg, uint8_t slot_id, uint16_t session_number);
typedef int (*en50221_app_rm_enq_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number);
/**
* Type definition for profile_reply callback function - called when we receive
@ -57,9 +58,11 @@ typedef int (*en50221_app_rm_enq_callback)(void *arg, uint8_t slot_id, uint16_t
* @param resource_ids The resource ids themselves.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_rm_reply_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint32_t resource_id_count,
uint32_t *resource_ids);
typedef int (*en50221_app_rm_reply_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id_count,
uint32_t *resource_ids);
/**
* Type definition for profile_changed callback function - called when we receive
* a profile_changed from a CAM.
@ -69,14 +72,16 @@ typedef int (*en50221_app_rm_reply_callback)(void *arg, uint8_t slot_id, uint16_
* @param session_number Session number concerned.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_rm_changed_callback)(void *arg, uint8_t slot_id, uint16_t session_number);
typedef int (*en50221_app_rm_changed_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number);
/**
* Opaque type representing a resource manager.
*/
typedef void *en50221_app_rm;
struct en50221_app_rm;
/**
* Create an instance of the resource manager.
@ -84,14 +89,14 @@ typedef void *en50221_app_rm;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_rm en50221_app_rm_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_rm *en50221_app_rm_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the resource manager.
*
* @param rm Instance to destroy.
*/
extern void en50221_app_rm_destroy(en50221_app_rm rm);
extern void en50221_app_rm_destroy(struct en50221_app_rm *rm);
/**
* Register the callback for when we receive a profile_enq from a CAM.
@ -100,8 +105,9 @@ extern void en50221_app_rm_destroy(en50221_app_rm rm);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_rm_register_enq_callback(en50221_app_rm rm,
en50221_app_rm_enq_callback callback, void *arg);
extern void en50221_app_rm_register_enq_callback(struct en50221_app_rm *rm,
en50221_app_rm_enq_callback callback,
void *arg);
/**
* Register the callback for when we receive a profile_reply from a CAM.
@ -110,8 +116,9 @@ extern void en50221_app_rm_register_enq_callback(en50221_app_rm rm,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_rm_register_reply_callback(en50221_app_rm rm,
en50221_app_rm_reply_callback callback, void *arg);
extern void en50221_app_rm_register_reply_callback(struct en50221_app_rm *rm,
en50221_app_rm_reply_callback callback,
void *arg);
/**
* Register the callback for when we receive a profile_changed from a CAM.
@ -120,8 +127,9 @@ extern void en50221_app_rm_register_reply_callback(en50221_app_rm rm,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_rm_register_changed_callback(en50221_app_rm rm,
en50221_app_rm_changed_callback callback, void *arg);
extern void en50221_app_rm_register_changed_callback(struct en50221_app_rm *rm,
en50221_app_rm_changed_callback callback,
void *arg);
/**
* Send a profile_enq to a CAM.
@ -130,7 +138,7 @@ extern void en50221_app_rm_register_changed_callback(en50221_app_rm rm,
* @param session_number Session number to send it on.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_rm_enq(en50221_app_rm rm, uint16_t session_number);
extern int en50221_app_rm_enq(struct en50221_app_rm *rm, uint16_t session_number);
/**
* Send a profile_reply to a CAM.
@ -141,9 +149,10 @@ extern int en50221_app_rm_enq(en50221_app_rm rm, uint16_t session_number);
* @param resource_ids The resource IDs themselves
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_rm_reply(en50221_app_rm rm, uint16_t session_number,
uint32_t resource_id_count,
uint32_t *resource_ids);
extern int en50221_app_rm_reply(struct en50221_app_rm *rm,
uint16_t session_number,
uint32_t resource_id_count,
uint32_t * resource_ids);
/**
* Send a profile_changed to a CAM.
@ -152,7 +161,7 @@ extern int en50221_app_rm_reply(en50221_app_rm rm, uint16_t session_number,
* @param session_number Session number to send it on.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_rm_changed(en50221_app_rm rm, uint16_t session_number);
extern int en50221_app_rm_changed(struct en50221_app_rm *rm, uint16_t session_number);
/**
* Pass data received for this resource into it for parsing.
@ -165,14 +174,14 @@ extern int en50221_app_rm_changed(en50221_app_rm rm, uint16_t session_number);
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_rm_message(en50221_app_rm rm,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_rm_message(struct en50221_app_rm *rm,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -28,188 +28,186 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_smartcard_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_smartcard {
struct en50221_app_send_functions *funcs;
en50221_app_smartcard_command_callback command_callback;
void *command_callback_arg;
en50221_app_smartcard_command_callback command_callback;
void *command_callback_arg;
en50221_app_smartcard_send_callback send_callback;
void *send_callback_arg;
en50221_app_smartcard_send_callback send_callback;
void *send_callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_smartcard_parse_command(struct en50221_app_smartcard_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_smartcard_parse_command(struct en50221_app_smartcard *smartcard,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
static int en50221_app_smartcard_parse_send(struct en50221_app_smartcard_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_smartcard_parse_send(struct en50221_app_smartcard *smartcard,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_smartcard en50221_app_smartcard_create(struct en50221_app_send_functions *funcs)
struct en50221_app_smartcard *en50221_app_smartcard_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_smartcard_private *private = NULL;
struct en50221_app_smartcard *smartcard = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_smartcard_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->command_callback = NULL;
private->send_callback = NULL;
// create structure and set it up
smartcard = malloc(sizeof(struct en50221_app_smartcard));
if (smartcard == NULL) {
return NULL;
}
smartcard->funcs = funcs;
smartcard->command_callback = NULL;
smartcard->send_callback = NULL;
pthread_mutex_init(&private->lock, NULL);
pthread_mutex_init(&smartcard->lock, NULL);
// done
return private;
// done
return smartcard;
}
void en50221_app_smartcard_destroy(en50221_app_smartcard smartcard)
void en50221_app_smartcard_destroy(struct en50221_app_smartcard *smartcard)
{
struct en50221_app_smartcard_private *private = (struct en50221_app_smartcard_private *) smartcard;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&smartcard->lock);
free(smartcard);
}
void en50221_app_smartcard_register_command_callback(en50221_app_smartcard smartcard,
en50221_app_smartcard_command_callback callback, void *arg)
void en50221_app_smartcard_register_command_callback(struct en50221_app_smartcard *smartcard,
en50221_app_smartcard_command_callback callback, void *arg)
{
struct en50221_app_smartcard_private *private = (struct en50221_app_smartcard_private *) smartcard;
pthread_mutex_lock(&private->lock);
private->command_callback = callback;
private->command_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&smartcard->lock);
smartcard->command_callback = callback;
smartcard->command_callback_arg = arg;
pthread_mutex_unlock(&smartcard->lock);
}
void en50221_app_smartcard_register_send_callback(en50221_app_smartcard smartcard,
en50221_app_smartcard_send_callback callback, void *arg)
void en50221_app_smartcard_register_send_callback(struct en50221_app_smartcard *smartcard,
en50221_app_smartcard_send_callback callback, void *arg)
{
struct en50221_app_smartcard_private *private = (struct en50221_app_smartcard_private *) smartcard;
pthread_mutex_lock(&private->lock);
private->send_callback = callback;
private->send_callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&smartcard->lock);
smartcard->send_callback = callback;
smartcard->send_callback_arg = arg;
pthread_mutex_unlock(&smartcard->lock);
}
int en50221_app_smartcard_command_reply(en50221_app_smartcard smartcard,
uint16_t session_number,
uint8_t reply_id,
uint8_t status,
uint8_t *data,
uint32_t data_length)
int en50221_app_smartcard_command_reply(struct en50221_app_smartcard *smartcard,
uint16_t session_number,
uint8_t reply_id, uint8_t status,
uint8_t *data,
uint32_t data_length)
{
struct en50221_app_smartcard_private *private = (struct en50221_app_smartcard_private *) smartcard;
uint8_t hdr[10];
struct iovec iovec[2];
int iov_count = 0;
// the tag
hdr[0] = (TAG_SMARTCARD_REPLY >> 16) & 0xFF;
hdr[1] = (TAG_SMARTCARD_REPLY >> 8) & 0xFF;
hdr[2] = TAG_SMARTCARD_REPLY & 0xFF;
// the rest of the data
if (reply_id == SMARTCARD_REPLY_ID_ANSW_TO_RESET) {
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(data_length+2, data+3, 3)) < 0) {
return -1;
}
// the rest of the header
hdr[3+length_field_len] = reply_id;
hdr[3+length_field_len+1] = status;
iovec[0].iov_base = hdr;
iovec[0].iov_len = 3+length_field_len+2;
// the data
iovec[1].iov_base = data;
iovec[1].iov_len = data_length;
iov_count = 2;
} else {
hdr[3] = 2;
hdr[4] = reply_id;
hdr[5] = status;
iovec[0].iov_base = data;
iovec[0].iov_len = 6;
iov_count = 1;
}
return private->funcs->send_datav(private->funcs->arg, session_number, iovec, iov_count);
uint8_t hdr[10];
struct iovec iovec[2];
int iov_count = 0;
// the tag
hdr[0] = (TAG_SMARTCARD_REPLY >> 16) & 0xFF;
hdr[1] = (TAG_SMARTCARD_REPLY >> 8) & 0xFF;
hdr[2] = TAG_SMARTCARD_REPLY & 0xFF;
// the rest of the data
if (reply_id == SMARTCARD_REPLY_ID_ANSW_TO_RESET) {
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(data_length + 2, data + 3, 3)) < 0) {
return -1;
}
// the rest of the header
hdr[3 + length_field_len] = reply_id;
hdr[3 + length_field_len + 1] = status;
iovec[0].iov_base = hdr;
iovec[0].iov_len = 3 + length_field_len + 2;
// the data
iovec[1].iov_base = data;
iovec[1].iov_len = data_length;
iov_count = 2;
} else {
hdr[3] = 2;
hdr[4] = reply_id;
hdr[5] = status;
iovec[0].iov_base = data;
iovec[0].iov_len = 6;
iov_count = 1;
}
return smartcard->funcs->send_datav(smartcard->funcs->arg, session_number, iovec, iov_count);
}
int en50221_app_smartcard_receive(en50221_app_smartcard smartcard,
uint16_t session_number,
uint8_t *data,
uint32_t data_length,
uint8_t SW1,
uint8_t SW2)
int en50221_app_smartcard_receive(struct en50221_app_smartcard *smartcard,
uint16_t session_number,
uint8_t *data,
uint32_t data_length,
uint8_t SW1, uint8_t SW2)
{
struct en50221_app_smartcard_private *private = (struct en50221_app_smartcard_private *) smartcard;
uint8_t buf[10];
uint8_t trailer[10];
// set up the tag
buf[0] = (TAG_SMARTCARD_RCV >> 16) & 0xFF;
buf[1] = (TAG_SMARTCARD_RCV >> 8) & 0xFF;
buf[2] = TAG_SMARTCARD_RCV & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(data_length+2, buf+3, 3)) < 0) {
return -1;
}
// set up the trailer
trailer[0] = SW1;
trailer[1] = SW2;
// build the iovecs
struct iovec iov[3];
iov[0].iov_base = buf;
iov[0].iov_len = 3+length_field_len;
iov[1].iov_base = data;
iov[1].iov_len = data_length;
iov[2].iov_base = trailer;
iov[2].iov_len = 2;
// create the data and send it
return private->funcs->send_datav(private->funcs->arg, session_number, iov, 3);
uint8_t buf[10];
uint8_t trailer[10];
// set up the tag
buf[0] = (TAG_SMARTCARD_RCV >> 16) & 0xFF;
buf[1] = (TAG_SMARTCARD_RCV >> 8) & 0xFF;
buf[2] = TAG_SMARTCARD_RCV & 0xFF;
// encode the length field
int length_field_len;
if ((length_field_len = asn_1_encode(data_length + 2, buf + 3, 3)) < 0) {
return -1;
}
// set up the trailer
trailer[0] = SW1;
trailer[1] = SW2;
// build the iovecs
struct iovec iov[3];
iov[0].iov_base = buf;
iov[0].iov_len = 3 + length_field_len;
iov[1].iov_base = data;
iov[1].iov_len = data_length;
iov[2].iov_base = trailer;
iov[2].iov_len = 2;
// create the data and send it
return smartcard->funcs->send_datav(smartcard->funcs->arg,
session_number, iov, 3);
}
int en50221_app_smartcard_message(en50221_app_smartcard smartcard,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_smartcard_message(struct en50221_app_smartcard *smartcard,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
{
struct en50221_app_smartcard_private *private = (struct en50221_app_smartcard_private *) smartcard;
(void)resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_SMARTCARD_COMMAND:
return en50221_app_smartcard_parse_command(private, slot_id, session_number, data+3, data_length-3);
case TAG_SMARTCARD_SEND:
return en50221_app_smartcard_parse_send(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_SMARTCARD_COMMAND:
return en50221_app_smartcard_parse_command(smartcard,
slot_id,
session_number,
data + 3,
data_length - 3);
case TAG_SMARTCARD_SEND:
return en50221_app_smartcard_parse_send(smartcard, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
@ -218,76 +216,81 @@ int en50221_app_smartcard_message(en50221_app_smartcard smartcard,
static int en50221_app_smartcard_parse_command(struct en50221_app_smartcard_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_smartcard_parse_command(struct en50221_app_smartcard *smartcard,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t command_id = data[1];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_smartcard_command_callback cb = private->command_callback;
void *cb_arg = private->command_callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, command_id);
}
return 0;
if (data_length != 2) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (data[0] != 1) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t command_id = data[1];
// tell the app
pthread_mutex_lock(&smartcard->lock);
en50221_app_smartcard_command_callback cb = smartcard->command_callback;
void *cb_arg = smartcard->command_callback_arg;
pthread_mutex_unlock(&smartcard->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, command_id);
}
return 0;
}
static int en50221_app_smartcard_parse_send(struct en50221_app_smartcard_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_smartcard_parse_send(struct en50221_app_smartcard *smartcard,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length)
{
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length < 8) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length-length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
data += length_field_len;
// parse
uint8_t CLA = data[0];
uint8_t INS = data[1];
uint8_t P1 = data[2];
uint8_t P2 = data[3];
uint16_t length_in = (data[4]<<8)|data[5];
uint8_t *data_in = data + 6;
// validate the length
if ((length_in + 8) != asn_data_length) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint16_t length_out = (data[6+length_in]<<8)|data[6+length_in+1];
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_smartcard_send_callback cb = private->send_callback;
void *cb_arg = private->send_callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, CLA, INS, P1, P2, data_in, length_in, length_out);
}
return 0;
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length < 8) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
data += length_field_len;
// parse
uint8_t CLA = data[0];
uint8_t INS = data[1];
uint8_t P1 = data[2];
uint8_t P2 = data[3];
uint16_t length_in = (data[4] << 8) | data[5];
uint8_t *data_in = data + 6;
// validate the length
if ((length_in + 8) != asn_data_length) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint16_t length_out =
(data[6 + length_in] << 8) | data[6 + length_in + 1];
// tell the app
pthread_mutex_lock(&smartcard->lock);
en50221_app_smartcard_send_callback cb = smartcard->send_callback;
void *cb_arg = smartcard->send_callback_arg;
pthread_mutex_unlock(&smartcard->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, CLA, INS, P1,
P2, data_in, length_in, length_out);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_smartcard_H__
#define __EN50221_APPLICATION_smartcard_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -68,8 +67,10 @@ extern "C"
* @param command_id One of the SMARTCARD_COMMAND_ID_* values
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_smartcard_command_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t command_id);
typedef int (*en50221_app_smartcard_command_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t command_id);
/**
* Type definition for command - called when we receive a send command.
@ -86,15 +87,21 @@ typedef int (*en50221_app_smartcard_command_callback)(void *arg, uint8_t slot_id
* @param out_length Number of bytes expected.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_smartcard_send_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t CLA, uint8_t INS, uint8_t P1, uint8_t P2,
uint8_t *in, uint32_t in_length,
uint32_t out_length);
typedef int (*en50221_app_smartcard_send_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t CLA,
uint8_t INS,
uint8_t P1,
uint8_t P2,
uint8_t *in,
uint32_t in_length,
uint32_t out_length);
/**
* Opaque type representing a smartcard resource.
*/
typedef void *en50221_app_smartcard;
struct en50221_app_smartcard;
/**
* Create an instance of the smartcard resource.
@ -102,14 +109,15 @@ typedef void *en50221_app_smartcard;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_smartcard en50221_app_smartcard_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_smartcard *
en50221_app_smartcard_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the smartcard resource.
*
* @param smartcard Instance to destroy.
*/
extern void en50221_app_smartcard_destroy(en50221_app_smartcard smartcard);
extern void en50221_app_smartcard_destroy(struct en50221_app_smartcard *smartcard);
/**
* Register the callback for when we receive a comms command.
@ -118,8 +126,9 @@ extern void en50221_app_smartcard_destroy(en50221_app_smartcard smartcard);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_smartcard_register_command_callback(en50221_app_smartcard smartcard,
en50221_app_smartcard_command_callback callback, void *arg);
extern void en50221_app_smartcard_register_command_callback(struct en50221_app_smartcard *smartcard,
en50221_app_smartcard_command_callback callback,
void *arg);
/**
* Register the callback for when we receive data to send.
@ -128,8 +137,9 @@ extern void en50221_app_smartcard_register_command_callback(en50221_app_smartcar
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_smartcard_register_send_callback(en50221_app_smartcard smartcard,
en50221_app_smartcard_send_callback callback, void *arg);
extern void en50221_app_smartcard_register_send_callback(struct en50221_app_smartcard *smartcard,
en50221_app_smartcard_send_callback callback,
void *arg);
/**
* Send a command response to the CAM.
@ -142,12 +152,12 @@ extern void en50221_app_smartcard_register_send_callback(en50221_app_smartcard s
* @param data_length Length of data to send.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_smartcard_command_reply(en50221_app_smartcard smartcard,
uint16_t session_number,
uint8_t reply_id,
uint8_t status,
uint8_t *data,
uint32_t data_length);
extern int en50221_app_smartcard_command_reply(struct en50221_app_smartcard *smartcard,
uint16_t session_number,
uint8_t reply_id,
uint8_t status,
uint8_t * data,
uint32_t data_length);
/**
* Send data received from a smartcart to the CAM.
@ -160,12 +170,11 @@ extern int en50221_app_smartcard_command_reply(en50221_app_smartcard smartcard,
* @param SW2 SW2 value.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_smartcard_receive(en50221_app_smartcard smartcard,
uint16_t session_number,
uint8_t *data,
uint32_t data_length,
uint8_t SW1,
uint8_t SW2);
extern int en50221_app_smartcard_receive(struct en50221_app_smartcard *smartcard,
uint16_t session_number,
uint8_t * data,
uint32_t data_length,
uint8_t SW1, uint8_t SW2);
/**
* Pass data received for this resource into it for parsing.
@ -178,14 +187,14 @@ extern int en50221_app_smartcard_receive(en50221_app_smartcard smartcard,
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_smartcard_message(en50221_app_smartcard smartcard,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_smartcard_message(struct en50221_app_smartcard *smartcard,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
This library is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APP_TAGS_H__
@ -25,7 +25,7 @@
/* Resource Manager */
#define TAG_PROFILE_ENQUIRY 0x9f8010
#define TAG_PROFILE 0x9f8011
#define TAG_PROFILE 0x9f8011
#define TAG_PROFILE_CHANGE 0x9f8012
/* Application Info */
@ -85,20 +85,20 @@
#define TAG_COMMS_RECV_MORE 0x9f8c06
/* Authentication */
#define TAG_AUTH_REQ 0x9f8200
#define TAG_AUTH_RESP 0x9f8201
#define TAG_AUTH_REQ 0x9f8200
#define TAG_AUTH_RESP 0x9f8201
/* Teletext */
#define TAG_TELETEXT_EBU 0x9f9000
#define TAG_TELETEXT_EBU 0x9f9000
/* Smartcard */
#define TAG_SMARTCARD_COMMAND 0x9f8e00
#define TAG_SMARTCARD_REPLY 0x9f8e01
#define TAG_SMARTCARD_SEND 0x9f8e02
#define TAG_SMARTCARD_RCV 0x9f8e03
#define TAG_SMARTCARD_COMMAND 0x9f8e00
#define TAG_SMARTCARD_REPLY 0x9f8e01
#define TAG_SMARTCARD_SEND 0x9f8e02
#define TAG_SMARTCARD_RCV 0x9f8e03
/* EPG */
#define TAG_EPG_ENQUIRY 0x9f8f00
#define TAG_EPG_REPLY 0x9f8f01
#define TAG_EPG_ENQUIRY 0x9f8f00
#define TAG_EPG_REPLY 0x9f8f01
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
@ -28,112 +28,114 @@
#include "en50221_app_tags.h"
#include "asn_1.h"
struct en50221_app_teletext_private {
struct en50221_app_send_functions *funcs;
struct en50221_app_teletext {
struct en50221_app_send_functions *funcs;
en50221_app_teletext_callback callback;
void *callback_arg;
en50221_app_teletext_callback callback;
void *callback_arg;
pthread_mutex_t lock;
pthread_mutex_t lock;
};
static int en50221_app_teletext_parse_ebu(struct en50221_app_teletext_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length);
static int en50221_app_teletext_parse_ebu(struct en50221_app_teletext *teletext,
uint8_t slot_id,
uint16_t session_number,
uint8_t * data,
uint32_t data_length);
en50221_app_teletext en50221_app_teletext_create(struct en50221_app_send_functions *funcs)
struct en50221_app_teletext *
en50221_app_teletext_create(struct en50221_app_send_functions *funcs)
{
struct en50221_app_teletext_private *private = NULL;
struct en50221_app_teletext *teletext = NULL;
// create structure and set it up
private = malloc(sizeof(struct en50221_app_teletext_private));
if (private == NULL) {
return NULL;
}
private->funcs = funcs;
private->callback = NULL;
// create structure and set it up
teletext = malloc(sizeof(struct en50221_app_teletext));
if (teletext == NULL) {
return NULL;
}
teletext->funcs = funcs;
teletext->callback = NULL;
pthread_mutex_init(&private->lock, NULL);
pthread_mutex_init(&teletext->lock, NULL);
// done
return private;
// done
return teletext;
}
void en50221_app_teletext_destroy(en50221_app_teletext teletext)
void en50221_app_teletext_destroy(struct en50221_app_teletext *teletext)
{
struct en50221_app_teletext_private *private = (struct en50221_app_teletext_private *) teletext;
pthread_mutex_destroy(&private->lock);
free(private);
pthread_mutex_destroy(&teletext->lock);
free(teletext);
}
void en50221_app_teletext_register_callback(en50221_app_teletext teletext,
en50221_app_teletext_callback callback, void *arg)
void en50221_app_teletext_register_callback(struct en50221_app_teletext *teletext,
en50221_app_teletext_callback callback, void *arg)
{
struct en50221_app_teletext_private *private = (struct en50221_app_teletext_private *) teletext;
pthread_mutex_lock(&private->lock);
private->callback = callback;
private->callback_arg = arg;
pthread_mutex_unlock(&private->lock);
pthread_mutex_lock(&teletext->lock);
teletext->callback = callback;
teletext->callback_arg = arg;
pthread_mutex_unlock(&teletext->lock);
}
int en50221_app_teletext_message(en50221_app_teletext teletext,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length)
int en50221_app_teletext_message(struct en50221_app_teletext *teletext,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data, uint32_t data_length)
{
struct en50221_app_teletext_private *private = (struct en50221_app_teletext_private *) teletext;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch(tag)
{
case TAG_TELETEXT_EBU:
return en50221_app_teletext_parse_ebu(private, slot_id, session_number, data+3, data_length-3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
(void) resource_id;
// get the tag
if (data_length < 3) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
switch (tag) {
case TAG_TELETEXT_EBU:
return en50221_app_teletext_parse_ebu(teletext, slot_id,
session_number,
data + 3,
data_length - 3);
}
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
return -1;
}
static int en50221_app_teletext_parse_ebu(struct en50221_app_teletext_private *private,
uint8_t slot_id, uint16_t session_number,
uint8_t *data, uint32_t data_length)
static int en50221_app_teletext_parse_ebu(struct en50221_app_teletext *teletext,
uint8_t slot_id,
uint16_t session_number,
uint8_t *data,
uint32_t data_length)
{
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length > (data_length-length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *teletext_data = data + length_field_len;
// tell the app
pthread_mutex_lock(&private->lock);
en50221_app_teletext_callback cb = private->callback;
void *cb_arg = private->callback_arg;
pthread_mutex_unlock(&private->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, teletext_data, asn_data_length);
}
return 0;
// first of all, decode the length field
uint16_t asn_data_length;
int length_field_len;
if ((length_field_len = asn_1_decode(&asn_data_length, data, data_length)) < 0) {
print(LOG_LEVEL, ERROR, 1, "ASN.1 decode error\n");
return -1;
}
// check it
if (asn_data_length > (data_length - length_field_len)) {
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
return -1;
}
uint8_t *teletext_data = data + length_field_len;
// tell the app
pthread_mutex_lock(&teletext->lock);
en50221_app_teletext_callback cb = teletext->callback;
void *cb_arg = teletext->callback_arg;
pthread_mutex_unlock(&teletext->lock);
if (cb) {
return cb(cb_arg, slot_id, session_number, teletext_data,
asn_data_length);
}
return 0;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APPLICATION_teletext_H__
#define __EN50221_APPLICATION_teletext_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -46,14 +45,16 @@ extern "C"
* @param teletext_data_lenghth Number of bytes.
* @return 0 on success, -1 on failure.
*/
typedef int (*en50221_app_teletext_callback)(void *arg, uint8_t slot_id, uint16_t session_number,
uint8_t *teletext_data,
uint32_t teletext_data_length);
typedef int (*en50221_app_teletext_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint8_t *teletext_data,
uint32_t teletext_data_length);
/**
* Opaque type representing a teletext resource.
*/
typedef void *en50221_app_teletext;
struct en50221_app_teletext;
/**
* Create an instance of the teletext resource.
@ -61,14 +62,15 @@ typedef void *en50221_app_teletext;
* @param funcs Send functions to use.
* @return Instance, or NULL on failure.
*/
extern en50221_app_teletext en50221_app_teletext_create(struct en50221_app_send_functions *funcs);
extern struct en50221_app_teletext *
en50221_app_teletext_create(struct en50221_app_send_functions *funcs);
/**
* Destroy an instance of the teletext resource.
*
* @param teletext Instance to destroy.
*/
extern void en50221_app_teletext_destroy(en50221_app_teletext teletext);
extern void en50221_app_teletext_destroy(struct en50221_app_teletext *teletext);
/**
* Register the callback for when we receive a request.
@ -77,8 +79,9 @@ extern void en50221_app_teletext_destroy(en50221_app_teletext teletext);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_app_teletext_register_callback(en50221_app_teletext teletext,
en50221_app_teletext_callback callback, void *arg);
extern void en50221_app_teletext_register_callback(struct en50221_app_teletext *teletext,
en50221_app_teletext_callback callback,
void *arg);
/**
* Pass data received for this resource into it for parsing.
@ -91,14 +94,14 @@ extern void en50221_app_teletext_register_callback(en50221_app_teletext teletext
* @param data_length Length of data in bytes.
* @return 0 on success, -1 on failure.
*/
extern int en50221_app_teletext_message(en50221_app_teletext teletext,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t *data, uint32_t data_length);
extern int en50221_app_teletext_message(struct en50221_app_teletext *teletext,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data,
uint32_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,20 +18,21 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "en50221_app_utils.h"
struct en50221_app_public_resource_id *
en50221_app_decode_public_resource_id(struct en50221_app_public_resource_id *idf, uint32_t resource_id)
struct en50221_app_public_resource_id
*en50221_app_decode_public_resource_id(struct en50221_app_public_resource_id *idf,
uint32_t resource_id)
{
// reject private resources
if ((resource_id & 0xc0000000) == 0xc0000000)
return NULL;
// reject private resources
if ((resource_id & 0xc0000000) == 0xc0000000)
return NULL;
idf->resource_class = (resource_id >> 16) & 0xffff; // use the resource_id as the MSBs of class
idf->resource_type = (resource_id >> 6) & 0x3ff;
idf->resource_version = resource_id & 0x3f;
return idf;
idf->resource_class = (resource_id >> 16) & 0xffff; // use the resource_id as the MSBs of class
idf->resource_type = (resource_id >> 6) & 0x3ff;
idf->resource_version = resource_id & 0x3f;
return idf;
}

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,15 +18,14 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EN50221_APP_UTILS_H__
#define __EN50221_APP_UTILS_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -41,30 +40,39 @@ extern "C"
* would need special code for any private resource anyway.
*/
struct en50221_app_public_resource_id {
uint16_t resource_class;
uint16_t resource_type;
uint8_t resource_version;
uint16_t resource_class;
uint16_t resource_type;
uint8_t resource_version;
};
typedef int (*en50221_send_data) (void *arg,
uint16_t session_number,
uint8_t * data,
uint16_t data_length);
typedef int (*en50221_send_datav) (void *arg,
uint16_t session_number,
struct iovec * vector,
int iov_count);
/**
* An abstraction away from hardcoded send functions so different layers may be
* slotted in under the application layer.
*/
struct en50221_app_send_functions {
/**
* Argument to pass to these functions.
*/
void *arg;
/**
* Send data.
*/
int (*send_data)(void *arg, uint16_t session_number, uint8_t *data, uint16_t data_length);
/**
* Send vector data.
*/
int (*send_datav)(void *arg, uint16_t session_number, struct iovec *vector, int iov_count);
/**
* Argument to pass to these functions.
*/
void *arg;
/**
* Send data.
*/
en50221_send_data send_data;
/**
* Send vector data.
*/
en50221_send_datav send_datav;
};
/**
@ -85,7 +93,8 @@ struct en50221_app_send_functions {
* @return Pointer to idf on success, or NULL if this is not a public resource.
*/
struct en50221_app_public_resource_id *
en50221_app_decode_public_resource_id(struct en50221_app_public_resource_id *idf, uint32_t resource_id);
en50221_app_decode_public_resource_id(struct en50221_app_public_resource_id *idf,
uint32_t resource_id);
/**
* Encode an en50221_app_public_resource_id structure into a host-endian uint32_t.
@ -93,13 +102,11 @@ struct en50221_app_public_resource_id *
* @param idf Structure to encode.
* @return The encoded value
*/
static inline uint32_t en50221_app_encode_public_resource_id(struct en50221_app_public_resource_id *idf)
{
return MKRID(idf->resource_class, idf->resource_type, idf->resource_version);
static inline uint32_t en50221_app_encode_public_resource_id(struct en50221_app_public_resource_id *idf) {
return MKRID(idf->resource_class, idf->resource_type, idf->resource_version);
}
#ifdef __cplusplus
}
#endif
#endif

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 session layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,35 +18,32 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EN50221_ERRNO
#define EN50221_ERRNO 1
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#define EN50221ERR_CAREAD -1 /* error during read from CA device. */
#define EN50221ERR_CAWRITE -2 /* error during write to CA device. */
#define EN50221ERR_TIMEOUT -3 /* timeout occured waiting for a response from a device. */
#define EN50221ERR_BADSLOTID -4 /* bad slot ID supplied by user - the offending slot_id will not be set. */
#define EN50221ERR_BADCONNECTIONID -5 /* bad connection ID supplied by user. */
#define EN50221ERR_BADSTATE -6 /* slot/connection in the wrong state. */
#define EN50221ERR_BADCAMDATA -7 /* CAM supplied an invalid request. */
#define EN50221ERR_OUTOFMEMORY -8 /* memory allocation failed. */
#define EN50221ERR_ASNENCODE -9 /* ASN.1 encode failure - indicates library bug. */
#define EN50221ERR_OUTOFCONNECTIONS -10 /* no more connections available. */
#define EN50221ERR_OUTOFSLOTS -11 /* no more slots available - the offending slot_id will not be set. */
#define EN50221ERR_IOVLIMIT -12 /* Too many struct iovecs were used. */
#define EN50221ERR_BADSESSIONNUMBER -13 /* Bad session number suppplied by user. */
#define EN50221ERR_OUTOFSESSIONS -14 /* no more sessions available. */
#define EN50221ERR_CAREAD -1 /* error during read from CA device. */
#define EN50221ERR_CAWRITE -2 /* error during write to CA device. */
#define EN50221ERR_TIMEOUT -3 /* timeout occured waiting for a response from a device. */
#define EN50221ERR_BADSLOTID -4 /* bad slot ID supplied by user - the offending slot_id will not be set. */
#define EN50221ERR_BADCONNECTIONID -5 /* bad connection ID supplied by user. */
#define EN50221ERR_BADSTATE -6 /* slot/connection in the wrong state. */
#define EN50221ERR_BADCAMDATA -7 /* CAM supplied an invalid request. */
#define EN50221ERR_OUTOFMEMORY -8 /* memory allocation failed. */
#define EN50221ERR_ASNENCODE -9 /* ASN.1 encode failure - indicates library bug. */
#define EN50221ERR_OUTOFCONNECTIONS -10 /* no more connections available. */
#define EN50221ERR_OUTOFSLOTS -11 /* no more slots available - the offending slot_id will not be set. */
#define EN50221ERR_IOVLIMIT -12 /* Too many struct iovecs were used. */
#define EN50221ERR_BADSESSIONNUMBER -13 /* Bad session number suppplied by user. */
#define EN50221ERR_OUTOFSESSIONS -14 /* no more sessions available. */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 session layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian@jusst.de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@ -26,28 +26,27 @@
#define __EN50221_SESSION_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
#include <libdvben50221/en50221_transport.h>
#define S_SCALLBACK_REASON_CAMCONNECTING 0x00 // CAM originated session connecting to resource (check for availability)
#define S_SCALLBACK_REASON_CAMCONNECTED 0x01 // CAM originated session connection established succesfully
#define S_SCALLBACK_REASON_CAMCONNECTFAIL 0x02 // CAM originated session connection failed
#define S_SCALLBACK_REASON_CONNECTED 0x03 // Host originated session ACKed by CAM.
#define S_SCALLBACK_REASON_CONNECTFAIL 0x04 // Host originated session NACKed by CAM.
#define S_SCALLBACK_REASON_CLOSE 0x05 // Session closed
#define S_SCALLBACK_REASON_TC_CONNECT 0x06 // A host originated transport connection has been established.
#define S_SCALLBACK_REASON_TC_CAMCONNECT 0x07 // A CAM originated transport connection has been established.
#define S_SCALLBACK_REASON_CAMCONNECTING 0x00 // CAM originated session connecting to resource (check for availability)
#define S_SCALLBACK_REASON_CAMCONNECTED 0x01 // CAM originated session connection established succesfully
#define S_SCALLBACK_REASON_CAMCONNECTFAIL 0x02 // CAM originated session connection failed
#define S_SCALLBACK_REASON_CONNECTED 0x03 // Host originated session ACKed by CAM.
#define S_SCALLBACK_REASON_CONNECTFAIL 0x04 // Host originated session NACKed by CAM.
#define S_SCALLBACK_REASON_CLOSE 0x05 // Session closed
#define S_SCALLBACK_REASON_TC_CONNECT 0x06 // A host originated transport connection has been established.
#define S_SCALLBACK_REASON_TC_CAMCONNECT 0x07 // A CAM originated transport connection has been established.
/**
* Opaque type representing a session layer.
*/
typedef void *en50221_session_layer;
struct en50221_session_layer;
/**
* Type definition for resource callback function - called by session layer when data
@ -61,9 +60,12 @@ typedef void *en50221_session_layer;
* @param data_length Length of data in bytes.
* @return 0 on success, or -1 on failure.
*/
typedef int (*en50221_sl_resource_callback)(void *arg, uint8_t slot_id,
uint16_t session_number, uint32_t resource_id,
uint8_t *data, uint32_t data_length);
typedef int (*en50221_sl_resource_callback) (void *arg,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id,
uint8_t * data,
uint32_t data_length);
/**
* Type definition for resource lookup callback function - used by the session layer to
@ -80,9 +82,12 @@ typedef int (*en50221_sl_resource_callback)(void *arg, uint8_t slot_id,
* -2 if it exists, but had a lower version, or
* -3 if it exists, but was unavailable.
*/
typedef int (*en50221_sl_lookup_callback)(void *arg, uint8_t slot_id, uint32_t requested_resource_id,
en50221_sl_resource_callback *callback_out, void **arg_out,
uint32_t *resource_id_out);
typedef int (*en50221_sl_lookup_callback) (void *arg,
uint8_t slot_id,
uint32_t requested_resource_id,
en50221_sl_resource_callback * callback_out,
void **arg_out,
uint32_t *resource_id_out);
/**
@ -96,8 +101,10 @@ typedef int (*en50221_sl_lookup_callback)(void *arg, uint8_t slot_id, uint32_t r
* @param resource_id Resource id.
* @return 0 on sucess, or -1 on error.
*/
typedef int (*en50221_sl_session_callback)(void *arg, int reason,
uint8_t slot_id, uint16_t session_number, uint32_t resource_id);
typedef int (*en50221_sl_session_callback) (void *arg, int reason,
uint8_t slot_id,
uint16_t session_number,
uint32_t resource_id);
/**
* Construct a new instance of the session layer.
@ -106,14 +113,15 @@ typedef int (*en50221_sl_session_callback)(void *arg, int reason,
* @param max_sessions Maximum number of sessions supported.
* @return The en50221_session_layer instance, or NULL on error.
*/
extern en50221_session_layer en50221_sl_create(en50221_transport_layer tl, uint32_t max_sessions);
extern struct en50221_session_layer *en50221_sl_create(struct en50221_transport_layer *tl,
uint32_t max_sessions);
/**
* Destroy an instance of the session layer.
*
* @param tl The en50221_session_layer instance.
*/
extern void en50221_sl_destroy(en50221_session_layer sl);
extern void en50221_sl_destroy(struct en50221_session_layer *sl);
/**
* Gets the last error.
@ -121,7 +129,7 @@ extern void en50221_sl_destroy(en50221_session_layer sl);
* @param tl The en50221_session_layer instance.
* @return One of the EN50221ERR_* values.
*/
extern int en50221_sl_get_error(en50221_session_layer tl);
extern int en50221_sl_get_error(struct en50221_session_layer *tl);
/**
* Register the callback for resource lookup.
@ -130,8 +138,9 @@ extern int en50221_sl_get_error(en50221_session_layer tl);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_sl_register_lookup_callback(en50221_session_layer sl,
en50221_sl_lookup_callback callback, void *arg);
extern void en50221_sl_register_lookup_callback(struct en50221_session_layer *sl,
en50221_sl_lookup_callback callback,
void *arg);
/**
* Register the callback for informing about session from a cam.
@ -140,8 +149,9 @@ extern void en50221_sl_register_lookup_callback(en50221_session_layer sl,
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_sl_register_session_callback(en50221_session_layer sl,
en50221_sl_session_callback callback, void *arg);
extern void en50221_sl_register_session_callback(struct en50221_session_layer *sl,
en50221_sl_session_callback callback,
void *arg);
/**
* Create a new session to a module in a slot.
@ -153,9 +163,11 @@ extern void en50221_sl_register_session_callback(en50221_session_layer sl,
* @param arg Argument to pass to the callback.
* @return The new session_number, or -1 on error.
*/
extern int en50221_sl_create_session(en50221_session_layer sl, int slot_id, uint8_t connection_id,
uint32_t resource_id,
en50221_sl_resource_callback callback, void* arg);
extern int en50221_sl_create_session(struct en50221_session_layer *sl, int slot_id,
uint8_t connection_id,
uint32_t resource_id,
en50221_sl_resource_callback callback,
void *arg);
/**
* Destroy a session.
@ -164,7 +176,8 @@ extern int en50221_sl_create_session(en50221_session_layer sl, int slot_id, uint
* @param session_number The session to destroy.
* @return 0 on success, or -1 on error.
*/
extern int en50221_sl_destroy_session(en50221_session_layer sl, uint16_t session_number);
extern int en50221_sl_destroy_session(struct en50221_session_layer *sl,
uint16_t session_number);
/**
* this function is used to take a data-block, pack into
@ -176,7 +189,10 @@ extern int en50221_sl_destroy_session(en50221_session_layer sl, uint16_t session
* @param data_length Length of data in bytes.
* @return 0 on success, or -1 on error.
*/
extern int en50221_sl_send_data(en50221_session_layer sl, uint16_t session_number, uint8_t *data, uint16_t data_length);
extern int en50221_sl_send_data(struct en50221_session_layer *sl,
uint16_t session_number,
uint8_t * data,
uint16_t data_length);
/**
* this function is used to take a data-block, pack into
@ -188,8 +204,10 @@ extern int en50221_sl_send_data(en50221_session_layer sl, uint16_t session_numbe
* @param iov_count Number of elements in io vector.
* @return 0 on success, or -1 on error.
*/
extern int en50221_sl_send_datav(en50221_session_layer sl, uint16_t session_number,
struct iovec *vector, int iov_count);
extern int en50221_sl_send_datav(struct en50221_session_layer *sl,
uint16_t session_number,
struct iovec *vector,
int iov_count);
/**
* this is used to send a message to all sessions, linked
@ -202,11 +220,13 @@ extern int en50221_sl_send_datav(en50221_session_layer sl, uint16_t session_numb
* @param data_length Length of data in bytes.
* @return 0 on success, or -1 on error.
*/
extern int en50221_sl_broadcast_data(en50221_session_layer sl, int slot_id, uint32_t resource_id,
uint8_t *data, uint16_t data_length);
extern int en50221_sl_broadcast_data(struct en50221_session_layer *sl,
int slot_id,
uint32_t resource_id,
uint8_t * data,
uint16_t data_length);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,54 @@
/*
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <libdvbapi/dvbca.h>
#include "en50221_stdcam.h"
struct en50221_stdcam *en50221_stdcam_create(int adapter, int slotnum,
struct en50221_transport_layer *tl,
struct en50221_session_layer *sl)
{
struct en50221_stdcam *result = NULL;
int cafd = dvbca_open(adapter, 0);
if (cafd == -1)
return NULL;
int ca_type = dvbca_get_interface_type(cafd, slotnum);
switch(ca_type) {
case DVBCA_INTERFACE_LINK:
result = en50221_stdcam_llci_create(cafd, slotnum, tl, sl);
break;
case DVBCA_INTERFACE_HLCI:
result = en50221_stdcam_hlci_create(cafd, slotnum);
break;
}
if (result == NULL)
close(cafd);
return result;
}

@ -0,0 +1,102 @@
/*
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EN50221_STDCAM_H
#define EN50221_STDCAM_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include <libdvben50221/en50221_app_ai.h>
#include <libdvben50221/en50221_app_ca.h>
#include <libdvben50221/en50221_app_mmi.h>
#include <libdvben50221/en50221_session.h>
#include <libdvben50221/en50221_transport.h>
enum en50221_stdcam_status {
EN50221_STDCAM_CAM_NONE,
EN50221_STDCAM_CAM_INRESET,
EN50221_STDCAM_CAM_OK,
EN50221_STDCAM_CAM_BAD,
};
struct en50221_stdcam {
/* one of more of the following may be NULL if a CAM does not support it */
struct en50221_app_ai *ai_resource;
struct en50221_app_ca *ca_resource;
struct en50221_app_mmi *mmi_resource;
/* if any of these are -1, no connection is in place to this resource yet */
int ai_session_number;
int ca_session_number;
int mmi_session_number;
/* poll the stdcam instance */
enum en50221_stdcam_status (*poll)(struct en50221_stdcam *stdcam);
/* inform the stdcam of the current DVB time */
void (*dvbtime)(struct en50221_stdcam *stdcam, time_t dvbtime);
/* destroy the stdcam instance */
void (*destroy)(struct en50221_stdcam *stdcam, int closefd);
};
/**
* Create an instance of the STDCAM for an LLCI interface.
*
* @param cafd FD of the CA device.
* @param slotnum Slotnum on that CA device.
* @param tl Transport layer instance to use.
* @param sl Session layer instance to use.
* @return en50221_stdcam instance, or NULL on error.
*/
extern struct en50221_stdcam *en50221_stdcam_llci_create(int cafd, int slotnum,
struct en50221_transport_layer *tl,
struct en50221_session_layer *sl);
/**
* Create an instance of the STDCAM for an HLCI interface.
*
* @param cafd FD of the CA device.
* @param slotnum Slotnum on that CA device.
* @return en50221_stdcam instance, or NULL on error.
*/
extern struct en50221_stdcam *en50221_stdcam_hlci_create(int cafd, int slotnum);
/**
* Convenience method to create a STDCAM interface for a ca device on a particular adapter.
*
* @param adapter The DVB adapter concerned.
* @param slotnum The ca slot number on that adapter.
* @param tl Transport layer instance to use (unused for HLCI cams).
* @param sl Session layer instance to use (unused for HLCI cams).
* @return en50221_stdcam instance, or NULL on error.
*/
extern struct en50221_stdcam *en50221_stdcam_create(int adapter, int slotnum,
struct en50221_transport_layer *tl,
struct en50221_session_layer *sl);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,216 @@
/*
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <libdvbapi/dvbca.h>
#include "en50221_app_utils.h"
#include "en50221_app_tags.h"
#include "en50221_stdcam.h"
struct en50221_stdcam_hlci {
struct en50221_stdcam stdcam;
int cafd;
int slotnum;
int initialised;
struct en50221_app_send_functions sendfuncs;
};
static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd);
static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam);
static int hlci_cam_added(struct en50221_stdcam_hlci *hlci);
static int hlci_send_data(void *arg, uint16_t session_number,
uint8_t * data, uint16_t data_length);
static int hlci_send_datav(void *arg, uint16_t session_number,
struct iovec *vector, int iov_count);
struct en50221_stdcam *en50221_stdcam_hlci_create(int cafd, int slotnum)
{
// try and allocate space for the HLCI stdcam
struct en50221_stdcam_hlci *hlci =
malloc(sizeof(struct en50221_stdcam_hlci));
if (hlci == NULL) {
return NULL;
}
memset(hlci, 0, sizeof(struct en50221_stdcam_hlci));
// create the sendfuncs
hlci->sendfuncs.arg = hlci;
hlci->sendfuncs.send_data = hlci_send_data;
hlci->sendfuncs.send_datav = hlci_send_datav;
// create the resources (NOTE: we just use fake session numbers here)
hlci->stdcam.ai_resource = en50221_app_ai_create(&hlci->sendfuncs);
hlci->stdcam.ai_session_number = 0;
hlci->stdcam.ca_resource = en50221_app_ca_create(&hlci->sendfuncs);
hlci->stdcam.ca_session_number = 1;
// hlci->stdcam.mmi_resource = en50221_app_mmi_create(&hlci->sendfuncs);
hlci->stdcam.mmi_session_number = -1;
// done
hlci->stdcam.destroy = en50221_stdcam_hlci_destroy;
hlci->stdcam.poll = en50221_stdcam_hlci_poll;
hlci->slotnum = slotnum;
hlci->cafd = cafd;
return &hlci->stdcam;
}
static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd)
{
struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;
if (hlci->stdcam.ai_resource)
en50221_app_ai_destroy(hlci->stdcam.ai_resource);
if (hlci->stdcam.ca_resource)
en50221_app_ca_destroy(hlci->stdcam.ca_resource);
if (hlci->stdcam.mmi_resource)
en50221_app_mmi_destroy(hlci->stdcam.mmi_resource);
if (closefd)
close(hlci->cafd);
free(hlci);
}
static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam)
{
struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;
switch(dvbca_get_cam_state(hlci->cafd, hlci->slotnum)) {
case DVBCA_CAMSTATE_MISSING:
hlci->initialised = 0;
break;
case DVBCA_CAMSTATE_READY:
case DVBCA_CAMSTATE_INITIALISING:
if (!hlci->initialised)
hlci_cam_added(hlci);
break;
}
// delay to prevent busy loop
usleep(10);
if (!hlci->initialised) {
return EN50221_STDCAM_CAM_NONE;
}
return EN50221_STDCAM_CAM_OK;
}
static int hlci_cam_added(struct en50221_stdcam_hlci *hlci)
{
uint8_t buf[256];
int size;
// get application information
if (en50221_app_ai_enquiry(hlci->stdcam.ai_resource, 0)) {
return -EIO;
}
if ((size = dvbca_hlci_read(hlci->cafd, TAG_APP_INFO, buf, sizeof(buf))) < 0) {
return size;
}
if (en50221_app_ai_message(hlci->stdcam.ai_resource, 0, 0, EN50221_APP_AI_RESOURCEID, buf, size)) {
return -EIO;
}
// we forge a fake CA_INFO here so the main app works - since it will expect a CA_INFO
// this will be replaced with a proper call (below) when the driver support is there
buf[0] = TAG_CA_INFO >> 16;
buf[1] = (uint8_t) (TAG_CA_INFO >> 8);
buf[2] = (uint8_t) TAG_CA_INFO;
buf[3] = 0;
if (en50221_app_ca_message(hlci->stdcam.ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, 4)) {
return -EIO;
}
/*
// get CA information
if (en50221_app_ca_info_enq(ca_resource, 0)) {
fprintf(stderr, "Failed to send CA INFO enquiry\n");
cafd = -1;
return -1;
}
if ((size = dvbca_hlci_read(cafd, TAG_CA_INFO, buf, sizeof(buf))) < 0) {
fprintf(stderr, "Failed to read CA INFO\n");
cafd = -1;
return -1;
}
if (en50221_app_ca_message(ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, size)) {
fprintf(stderr, "Failed to parse CA INFO\n");
cafd = -1;
return -1;
}
*/
// done
hlci->initialised = 1;
return 0;
}
static int hlci_send_data(void *arg, uint16_t session_number,
uint8_t * data, uint16_t data_length)
{
(void) session_number;
struct en50221_stdcam_hlci *hlci = arg;
return dvbca_hlci_write(hlci->cafd, data, data_length);
}
static int hlci_send_datav(void *arg, uint16_t session_number,
struct iovec *vector, int iov_count)
{
(void) session_number;
struct en50221_stdcam_hlci *hlci = arg;
// calculate the total length of the data to send
uint32_t data_size = 0;
int i;
for (i = 0; i < iov_count; i++) {
data_size += vector[i].iov_len;
}
// allocate memory for it
uint8_t *buf = malloc(data_size);
if (buf == NULL) {
return -1;
}
// merge the iovecs
uint32_t pos = 0;
for (i = 0; i < iov_count; i++) {
memcpy(buf + pos, vector[i].iov_base, vector[i].iov_len);
pos += vector[i].iov_len;
}
// sendit and cleanup
int status = dvbca_hlci_write(hlci->cafd, buf, data_size);
free(buf);
return status;
}

@ -0,0 +1,437 @@
/*
en50221 encoder An implementation for libdvb
an implementation for the en50221 transport layer
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <libdvbapi/dvbca.h>
#include <libdvbmisc/dvbmisc.h>
#include "en50221_app_rm.h"
#include "en50221_app_datetime.h"
#include "en50221_app_utils.h"
#include "en50221_app_tags.h"
#include "en50221_stdcam.h"
#define LLCI_RESPONSE_TIMEOUT_MS 1000
#define LLCI_POLL_DELAY_MS 100
/* resource IDs we support */
static uint32_t resource_ids[] =
{ EN50221_APP_RM_RESOURCEID,
EN50221_APP_CA_RESOURCEID,
EN50221_APP_AI_RESOURCEID,
EN50221_APP_MMI_RESOURCEID,
EN50221_APP_DATETIME_RESOURCEID,
};
#define RESOURCE_IDS_COUNT sizeof(resource_ids)/4
struct llci_resource {
struct en50221_app_public_resource_id resid;
uint32_t binary_resource_id;
en50221_sl_resource_callback callback;
void *arg;
};
struct en50221_stdcam_llci {
struct en50221_stdcam stdcam;
int cafd;
int slotnum;
int state;
struct llci_resource resources[RESOURCE_IDS_COUNT];
struct en50221_transport_layer *tl;
struct en50221_session_layer *sl;
struct en50221_app_send_functions sendfuncs;
int tl_slot_id;
struct en50221_app_rm *rm_resource;
struct en50221_app_datetime *datetime_resource;
int datetime_session_number;
uint8_t datetime_response_interval;
time_t datetime_next_send;
time_t datetime_dvbtime;
};
static enum en50221_stdcam_status en50221_stdcam_llci_poll(struct en50221_stdcam *stdcam);
static void en50221_stdcam_llci_dvbtime(struct en50221_stdcam *stdcam, time_t dvbtime);
static void en50221_stdcam_llci_destroy(struct en50221_stdcam *stdcam, int closefd);
static void llci_cam_added(struct en50221_stdcam_llci *llci);
static void llci_cam_in_reset(struct en50221_stdcam_llci *llci);
static void llci_cam_removed(struct en50221_stdcam_llci *llci);
static int llci_lookup_callback(void *arg, uint8_t _slot_id, uint32_t requested_resource_id,
en50221_sl_resource_callback *callback_out, void **arg_out,
uint32_t *connected_resource_id);
static int llci_session_callback(void *arg, int reason, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id);
static int llci_rm_enq_callback(void *arg, uint8_t _slot_id, uint16_t session_number);
static int llci_rm_reply_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *_resource_ids);
static int llci_rm_changed_callback(void *arg, uint8_t _slot_id, uint16_t session_number);
static int llci_datetime_enquiry_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint8_t response_interval);
struct en50221_stdcam *en50221_stdcam_llci_create(int cafd, int slotnum,
struct en50221_transport_layer *tl,
struct en50221_session_layer *sl)
{
// try and allocate space for the LLCI stdcam
struct en50221_stdcam_llci *llci =
malloc(sizeof(struct en50221_stdcam_llci));
if (llci == NULL) {
return NULL;
}
memset(llci, 0, sizeof(struct en50221_stdcam_llci));
// create the sendfuncs
llci->sendfuncs.arg = sl;
llci->sendfuncs.send_data = (en50221_send_data) en50221_sl_send_data;
llci->sendfuncs.send_datav = (en50221_send_datav) en50221_sl_send_datav;
// create the resource manager resource
int resource_idx = 0;
llci->rm_resource = en50221_app_rm_create(&llci->sendfuncs);
en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_RM_RESOURCEID);
llci->resources[resource_idx].binary_resource_id = EN50221_APP_RM_RESOURCEID;
llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_rm_message;
llci->resources[resource_idx].arg = llci->rm_resource;
en50221_app_rm_register_enq_callback(llci->rm_resource, llci_rm_enq_callback, llci);
en50221_app_rm_register_reply_callback(llci->rm_resource, llci_rm_reply_callback, llci);
en50221_app_rm_register_changed_callback(llci->rm_resource, llci_rm_changed_callback, llci);
resource_idx++;
// create the datetime resource
llci->datetime_resource = en50221_app_datetime_create(&llci->sendfuncs);
en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_DATETIME_RESOURCEID);
llci->resources[resource_idx].binary_resource_id = EN50221_APP_DATETIME_RESOURCEID;
llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_datetime_message;
llci->resources[resource_idx].arg = llci->datetime_resource;
en50221_app_datetime_register_enquiry_callback(llci->datetime_resource, llci_datetime_enquiry_callback, llci);
resource_idx++;
llci->datetime_session_number = -1;
llci->datetime_response_interval = 0;
llci->datetime_next_send = 0;
llci->datetime_dvbtime = 0;
// create the application information resource
llci->stdcam.ai_resource = en50221_app_ai_create(&llci->sendfuncs);
en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_AI_RESOURCEID);
llci->resources[resource_idx].binary_resource_id = EN50221_APP_AI_RESOURCEID;
llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_ai_message;
llci->resources[resource_idx].arg = llci->stdcam.ai_resource;
llci->stdcam.ai_session_number = -1;
resource_idx++;
// create the CA resource
llci->stdcam.ca_resource = en50221_app_ca_create(&llci->sendfuncs);
en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_CA_RESOURCEID);
llci->resources[resource_idx].binary_resource_id = EN50221_APP_CA_RESOURCEID;
llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_ca_message;
llci->resources[resource_idx].arg = llci->stdcam.ca_resource;
llci->stdcam.ca_session_number = -1;
resource_idx++;
// create the MMI resource
llci->stdcam.mmi_resource = en50221_app_mmi_create(&llci->sendfuncs);
en50221_app_decode_public_resource_id(&llci->resources[resource_idx].resid, EN50221_APP_MMI_RESOURCEID);
llci->resources[resource_idx].binary_resource_id = EN50221_APP_MMI_RESOURCEID;
llci->resources[resource_idx].callback = (en50221_sl_resource_callback) en50221_app_mmi_message;
llci->resources[resource_idx].arg = llci->stdcam.mmi_resource;
llci->stdcam.mmi_session_number = -1;
resource_idx++;
// register session layer callbacks
en50221_sl_register_lookup_callback(sl, llci_lookup_callback, llci);
en50221_sl_register_session_callback(sl, llci_session_callback, llci);
// done
llci->stdcam.destroy = en50221_stdcam_llci_destroy;
llci->stdcam.poll = en50221_stdcam_llci_poll;
llci->stdcam.dvbtime = en50221_stdcam_llci_dvbtime;
llci->cafd = cafd;
llci->slotnum = slotnum;
llci->tl = tl;
llci->sl = sl;
llci->tl_slot_id = -1;
llci->state = EN50221_STDCAM_CAM_INRESET;
return &llci->stdcam;
}
static void en50221_stdcam_llci_dvbtime(struct en50221_stdcam *stdcam, time_t dvbtime)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) stdcam;
llci->datetime_dvbtime = dvbtime;
}
static void en50221_stdcam_llci_destroy(struct en50221_stdcam *stdcam, int closefd)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) stdcam;
// "remove" the cam
llci_cam_removed(llci);
// destroy resources
if (llci->rm_resource)
en50221_app_rm_destroy(llci->rm_resource);
if (llci->datetime_resource)
en50221_app_datetime_destroy(llci->datetime_resource);
if (llci->stdcam.ai_resource)
en50221_app_ai_destroy(llci->stdcam.ai_resource);
if (llci->stdcam.ca_resource)
en50221_app_ca_destroy(llci->stdcam.ca_resource);
if (llci->stdcam.mmi_resource)
en50221_app_mmi_destroy(llci->stdcam.mmi_resource);
if (closefd)
close(llci->cafd);
free(llci);
}
static enum en50221_stdcam_status en50221_stdcam_llci_poll(struct en50221_stdcam *stdcam)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) stdcam;
switch(dvbca_get_cam_state(llci->cafd, llci->slotnum)) {
case DVBCA_CAMSTATE_MISSING:
if (llci->state != EN50221_STDCAM_CAM_NONE)
llci_cam_removed(llci);
break;
case DVBCA_CAMSTATE_READY:
if (llci->state == EN50221_STDCAM_CAM_NONE)
llci_cam_added(llci);
else if (llci->state == EN50221_STDCAM_CAM_INRESET)
llci_cam_in_reset(llci);
break;
}
// poll the stack
int error;
if ((error = en50221_tl_poll(llci->tl)) != 0) {
print(LOG_LEVEL, ERROR, 1, "Error reported by stack:%i\n", en50221_tl_get_error(llci->tl));
}
// send date/time response
if (llci->datetime_session_number != -1) {
time_t cur_time = time(NULL);
if (llci->datetime_response_interval && (cur_time > llci->datetime_next_send)) {
en50221_app_datetime_send(llci->datetime_resource,
llci->datetime_session_number,
llci->datetime_dvbtime, 0);
llci->datetime_next_send = cur_time + llci->datetime_response_interval;
}
}
return llci->state;
}
static void llci_cam_added(struct en50221_stdcam_llci *llci)
{
// clear down any old structures
if (llci->tl_slot_id != -1) {
llci_cam_removed(llci);
}
// reset the CAM
dvbca_reset(llci->cafd, llci->slotnum);
llci->state = EN50221_STDCAM_CAM_INRESET;
}
static void llci_cam_in_reset(struct en50221_stdcam_llci *llci)
{
if (dvbca_get_cam_state(llci->cafd, llci->slotnum) != DVBCA_CAMSTATE_READY) {
return;
}
// register the slot
if ((llci->tl_slot_id = en50221_tl_register_slot(llci->tl, llci->cafd, llci->slotnum,
LLCI_RESPONSE_TIMEOUT_MS, LLCI_POLL_DELAY_MS)) < 0) {
llci->state = EN50221_STDCAM_CAM_BAD;
return;
}
// create a new connection on the slot
if (en50221_tl_new_tc(llci->tl, llci->tl_slot_id) < 0) {
llci->state = EN50221_STDCAM_CAM_BAD;
llci->tl_slot_id = -1;
en50221_tl_destroy_slot(llci->tl, llci->tl_slot_id);
return;
}
llci->state = EN50221_STDCAM_CAM_OK;
}
static void llci_cam_removed(struct en50221_stdcam_llci *llci)
{
if (llci->tl_slot_id != -1) {
en50221_tl_destroy_slot(llci->tl, llci->tl_slot_id);
llci->tl_slot_id = -1;
llci->datetime_session_number = -1;
llci->stdcam.ai_session_number = -1;
llci->stdcam.ca_session_number = -1;
llci->stdcam.mmi_session_number = -1;
}
llci->state = EN50221_STDCAM_CAM_NONE;
}
static int llci_lookup_callback(void *arg, uint8_t _slot_id, uint32_t requested_resource_id,
en50221_sl_resource_callback *callback_out, void **arg_out,
uint32_t *connected_resource_id)
{
struct en50221_app_public_resource_id resid;
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
(void) _slot_id;
// decode the resource id
if (!en50221_app_decode_public_resource_id(&resid, requested_resource_id)) {
return -1;
}
// try and find an instance of the resource
uint32_t i;
for(i=0; i<RESOURCE_IDS_COUNT; i++) {
if ((resid.resource_class == llci->resources[i].resid.resource_class) &&
(resid.resource_type == llci->resources[i].resid.resource_type)) {
// limit sessions to certain resources
switch(requested_resource_id) {
case EN50221_APP_DATETIME_RESOURCEID:
if (llci->datetime_session_number != -1)
return -3;
break;
case EN50221_APP_AI_RESOURCEID:
if (llci->stdcam.ai_session_number != -1)
return -3;
break;
case EN50221_APP_CA_RESOURCEID:
if (llci->stdcam.ca_session_number != -1)
return -3;
break;
case EN50221_APP_MMI_RESOURCEID:
if (llci->stdcam.mmi_session_number != -1)
return -3;
break;
}
// resource is ok.
*callback_out = llci->resources[i].callback;
*arg_out = llci->resources[i].arg;
*connected_resource_id = llci->resources[i].binary_resource_id;
return 0;
}
}
return -1;
}
static int llci_session_callback(void *arg, int reason, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
(void) _slot_id;
switch(reason) {
case S_SCALLBACK_REASON_CAMCONNECTED:
if (resource_id == EN50221_APP_RM_RESOURCEID) {
en50221_app_rm_enq(llci->rm_resource, session_number);
} else if (resource_id == EN50221_APP_DATETIME_RESOURCEID) {
llci->datetime_session_number = session_number;
} else if (resource_id == EN50221_APP_AI_RESOURCEID) {
en50221_app_ai_enquiry(llci->stdcam.ai_resource, session_number);
llci->stdcam.ai_session_number = session_number;
} else if (resource_id == EN50221_APP_CA_RESOURCEID) {
en50221_app_ca_info_enq(llci->stdcam.ca_resource, session_number);
llci->stdcam.ca_session_number = session_number;
} else if (resource_id == EN50221_APP_MMI_RESOURCEID) {
llci->stdcam.mmi_session_number = session_number;
}
break;
case S_SCALLBACK_REASON_CLOSE:
if (resource_id == EN50221_APP_MMI_RESOURCEID) {
llci->stdcam.mmi_session_number = -1;
}
break;
}
return 0;
}
static int llci_rm_enq_callback(void *arg, uint8_t _slot_id, uint16_t session_number)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
(void) _slot_id;
if (en50221_app_rm_reply(llci->rm_resource, session_number, RESOURCE_IDS_COUNT, resource_ids)) {
print(LOG_LEVEL, ERROR, 1, "Failed to send RM ENQ on slot %02x\n", _slot_id);
}
return 0;
}
static int llci_rm_reply_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint32_t resource_id_count, uint32_t *_resource_ids)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
(void) _slot_id;
(void) resource_id_count;
(void) _resource_ids;
if (en50221_app_rm_changed(llci->rm_resource, session_number)) {
print(LOG_LEVEL, ERROR, 1, "Failed to send RM REPLY on slot %02x\n", _slot_id);
}
return 0;
}
static int llci_rm_changed_callback(void *arg, uint8_t _slot_id, uint16_t session_number)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
(void) _slot_id;
if (en50221_app_rm_enq(llci->rm_resource, session_number)) {
print(LOG_LEVEL, ERROR, 1, "Failed to send RM CHANGED on slot %02x\n", _slot_id);
}
return 0;
}
static int llci_datetime_enquiry_callback(void *arg, uint8_t _slot_id, uint16_t session_number, uint8_t response_interval)
{
struct en50221_stdcam_llci *llci = (struct en50221_stdcam_llci *) arg;
(void) _slot_id;
llci->datetime_response_interval = response_interval;
llci->datetime_next_send = 0;
if (response_interval) {
llci->datetime_next_send = time(NULL) + response_interval;
}
en50221_app_datetime_send(llci->datetime_resource, session_number, llci->datetime_dvbtime, 0);
return 0;
}

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
en50221 encoder An implementation for libdvb
an implementation for the en50221 session layer
Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
@ -18,7 +18,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@ -26,8 +26,7 @@
#define __EN50221_TRANSPORT_H__
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include <stdlib.h>
@ -37,23 +36,23 @@ extern "C"
/**
* Callback reasons.
*/
#define T_CALLBACK_REASON_CONNECTIONOPEN 0x00 // A connection we opened _to_ the cam has been ACKed
#define T_CALLBACK_REASON_CAMCONNECTIONOPEN 0x01 // The cam has opened a connection to _us_.
#define T_CALLBACK_REASON_DATA 0x02 // Data received
#define T_CALLBACK_REASON_CONNECTIONCLOSE 0x03 // The cam has told us to close a connection.
#define T_CALLBACK_REASON_SLOTCLOSE 0x04 // The cam in the supplied slot id has been removed.
#define T_CALLBACK_REASON_CONNECTIONOPEN 0x00 // A connection we opened _to_ the cam has been ACKed
#define T_CALLBACK_REASON_CAMCONNECTIONOPEN 0x01 // The cam has opened a connection to _us_.
#define T_CALLBACK_REASON_DATA 0x02 // Data received
#define T_CALLBACK_REASON_CONNECTIONCLOSE 0x03 // The cam has told us to close a connection.
#define T_CALLBACK_REASON_SLOTCLOSE 0x04 // The cam in the supplied slot id has been removed.
// these are the states a TC can be in
#define T_STATE_IDLE 0x01 // this transport connection is not in use
#define T_STATE_ACTIVE 0x02 // this transport connection is in use
#define T_STATE_ACTIVE_DELETEQUEUED 0x04 // this transport connection is about to be deleted
#define T_STATE_IN_CREATION 0x08 // this transport waits for a T_C_T_C_REPLY to become active
#define T_STATE_IN_DELETION 0x10 // this transport waits for T_D_T_C_REPLY to become idle again
#define T_STATE_IDLE 0x01 // this transport connection is not in use
#define T_STATE_ACTIVE 0x02 // this transport connection is in use
#define T_STATE_ACTIVE_DELETEQUEUED 0x04 // this transport connection is about to be deleted
#define T_STATE_IN_CREATION 0x08 // this transport waits for a T_C_T_C_REPLY to become active
#define T_STATE_IN_DELETION 0x10 // this transport waits for T_D_T_C_REPLY to become idle again
/**
* Opaque type representing a transport layer.
*/
typedef void *en50221_transport_layer;
struct en50221_transport_layer;
/**
* Type definition for callback function - used when events are received from a module.
@ -72,9 +71,11 @@ typedef void *en50221_transport_layer;
* @param slot_id Slot_id the data was received from.
* @param connection_id Connection_id the data was received from.
*/
typedef void (*en50221_tl_callback)(void *arg, int reason,
uint8_t *data, uint32_t data_length,
uint8_t slot_id, uint8_t connection_id);
typedef void (*en50221_tl_callback) (void *arg, int reason,
uint8_t * data,
uint32_t data_length,
uint8_t slot_id,
uint8_t connection_id);
/**
@ -84,14 +85,15 @@ typedef void (*en50221_tl_callback)(void *arg, int reason,
* @param max_connections_per_slot Maximum connections per slot.
* @return The en50221_transport_layer instance, or NULL on error.
*/
extern en50221_transport_layer en50221_tl_create(uint8_t max_slots, uint8_t max_connections_per_slot);
extern struct en50221_transport_layer *en50221_tl_create(uint8_t max_slots,
uint8_t max_connections_per_slot);
/**
* Destroy an instance of the transport layer.
*
* @param tl The en50221_transport_layer instance.
*/
extern void en50221_tl_destroy(en50221_transport_layer tl);
extern void en50221_tl_destroy(struct en50221_transport_layer *tl);
/**
* Register a new slot with the library.
@ -103,9 +105,10 @@ extern void en50221_tl_destroy(en50221_transport_layer tl);
* @param poll_delay Interval between polls in ms.
* @return slot_id on sucess, or -1 on error.
*/
extern int en50221_tl_register_slot(en50221_transport_layer tl, int ca_hndl,
uint8_t slot, uint32_t response_timeout,
uint32_t poll_delay);
extern int en50221_tl_register_slot(struct en50221_transport_layer *tl,
int ca_hndl, uint8_t slot,
uint32_t response_timeout,
uint32_t poll_delay);
/**
* Destroy a registered slot - e.g. if a CAM is removed, or an error occurs. Does
@ -114,7 +117,7 @@ extern int en50221_tl_register_slot(en50221_transport_layer tl, int ca_hndl,
* @param tl The en50221_transport_layer instance.
* @param slot_id Slot to destroy.
*/
extern void en50221_tl_destroy_slot(en50221_transport_layer tl, uint8_t slot_id);
extern void en50221_tl_destroy_slot(struct en50221_transport_layer *tl, uint8_t slot_id);
/**
* Performs one iteration of the transport layer poll -
@ -126,7 +129,7 @@ extern void en50221_tl_destroy_slot(en50221_transport_layer tl, uint8_t slot_id)
* @param tl The en50221_transport_layer instance.
* @return 0 on succes, or -1 if there was an error of some sort.
*/
extern int en50221_tl_poll(en50221_transport_layer tl);
extern int en50221_tl_poll(struct en50221_transport_layer *tl);
/**
* Register the callback for data reception.
@ -135,8 +138,8 @@ extern int en50221_tl_poll(en50221_transport_layer tl);
* @param callback The callback. Set to NULL to remove the callback completely.
* @param arg Private data passed as arg0 of the callback.
*/
extern void en50221_tl_register_callback(en50221_transport_layer tl,
en50221_tl_callback callback, void *arg);
extern void en50221_tl_register_callback(struct en50221_transport_layer *tl,
en50221_tl_callback callback, void *arg);
/**
* Gets the ID of the slot an error occurred on.
@ -144,7 +147,7 @@ extern void en50221_tl_register_callback(en50221_transport_layer tl,
* @param tl The en50221_transport_layer instance.
* @return The offending slot id.
*/
extern int en50221_tl_get_error_slot(en50221_transport_layer tl);
extern int en50221_tl_get_error_slot(struct en50221_transport_layer *tl);
/**
* Gets the last error.
@ -152,7 +155,7 @@ extern int en50221_tl_get_error_slot(en50221_transport_layer tl);
* @param tl The en50221_transport_layer instance.
* @return One of the EN50221ERR_* values.
*/
extern int en50221_tl_get_error(en50221_transport_layer tl);
extern int en50221_tl_get_error(struct en50221_transport_layer *tl);
/**
* This function is used to take a data-block, pack into
@ -165,9 +168,11 @@ extern int en50221_tl_get_error(en50221_transport_layer tl);
* @param data_length Number of bytes to send.
* @return 0 on success, or -1 on error.
*/
extern int en50221_tl_send_data(en50221_transport_layer tl,
uint8_t slot_id, uint8_t connection_id,
uint8_t *data, uint32_t data_length);
extern int en50221_tl_send_data(struct en50221_transport_layer *tl,
uint8_t slot_id,
uint8_t connection_id,
uint8_t * data,
uint32_t data_length);
/**
* This function is used to take a data-block, pack into
@ -180,9 +185,9 @@ extern int en50221_tl_send_data(en50221_transport_layer tl,
* @param io_count Number of elements in vector.
* @return 0 on success, or -1 on error.
*/
extern int en50221_tl_send_datav(en50221_transport_layer tl, uint8_t slot_id,
uint8_t connection_id, struct iovec *vector,
int iov_count);
extern int en50221_tl_send_datav(struct en50221_transport_layer *tl,
uint8_t slot_id, uint8_t connection_id,
struct iovec *vector, int iov_count);
/**
* Create a new transport connection to the cam.
@ -196,7 +201,7 @@ extern int en50221_tl_send_datav(en50221_transport_layer tl, uint8_t slot_id,
* @param slot_id ID of the slot.
* @return The allocated connection id on success, or -1 on error.
*/
extern int en50221_tl_new_tc(en50221_transport_layer tl, uint8_t slot_id);
extern int en50221_tl_new_tc(struct en50221_transport_layer *tl, uint8_t slot_id);
/**
* Deallocates a transport connection.
@ -210,8 +215,7 @@ extern int en50221_tl_new_tc(en50221_transport_layer tl, uint8_t slot_id);
* @param connection_id Connection id to send the request _on_.
* @return 0 on success, or -1 on error.
*/
extern int en50221_tl_del_tc(en50221_transport_layer tl, uint8_t slot_id,
uint8_t connection_id);
extern int en50221_tl_del_tc(struct en50221_transport_layer *tl, uint8_t slot_id, uint8_t connection_id);
/**
* Checks the state of a connection.
@ -221,11 +225,10 @@ extern int en50221_tl_del_tc(en50221_transport_layer tl, uint8_t slot_id,
* @param connection_id Connection id to send the request _on_.
* @return One of the T_STATE_* values.
*/
extern int en50221_tl_get_connection_state(en50221_transport_layer tl,
uint8_t slot_id, uint8_t connection_id);
extern int en50221_tl_get_connection_state(struct en50221_transport_layer *tl,
uint8_t slot_id, uint8_t connection_id);
#ifdef __cplusplus
}
#endif
#endif

@ -1,7 +1,7 @@
/*
libdvbmisc - DVB miscellaneous library
Copyright (C) 2005 Manu Abraham <manu@kromtek.com>
Copyright (C) 2005 Manu Abraham <abraham.manu@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public

@ -1,6 +1,6 @@
noinst_LTLIBRARIES = libucsi.la
SUBDIRS = dvb mpeg .
SUBDIRS = dvb mpeg atsc .
INCLUDES = -I$(top_srcdir)/kaffeine/src/input/dvb/lib
@ -9,9 +9,11 @@ libucsi_la_SOURCES = crc32.c \
transport_packet.c
libucsi_la_LDFLAGS = ./mpeg \
./dvb
./dvb \
/atsc
libucsi_la_LIBADD = ./mpeg/libdvbmpeg.la \
./dvb/libdvbdvb.la
./dvb/libdvbdvb.la \
./atsc/libdvbatsc.la
CFLAGS = -g -O2 -Wall -Wshadow -Wpointer-arith -Wstrict-prototypes -fPIC

@ -0,0 +1,17 @@
noinst_LTLIBRARIES = libdvbatsc.la
INCLUDES = -I$(top_srcdir)/kaffeine/src/input/dvb/lib
libdvbatsc_la_SOURCES = atsc_text.c \
cvct_section.c \
dccsct_section.c \
dcct_section.c \
eit_section.c \
ett_section.c \
mgt_section.c \
rrt_section.c \
stt_section.c \
tvct_section.c \
types.c
CFLAGS = -g -O2 -Wall -Wshadow -Wpointer-arith -Wstrict-prototypes -fPIC

@ -0,0 +1,112 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_atsc@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_AC3_DESCRIPTOR
#define _UCSI_ATSC_AC3_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
enum atsc_ac3_channels {
ATSC_AC3_CHANNELS_1_PLUS_1 = 0x0,
ATSC_AC3_CHANNELS_1_0 = 0x1,
ATSC_AC3_CHANNELS_2_0 = 0x2,
ATSC_AC3_CHANNELS_3_0 = 0x3,
ATSC_AC3_CHANNELS_2_1 = 0x4,
ATSC_AC3_CHANNELS_3_1 = 0x5,
ATSC_AC3_CHANNELS_2_2 = 0x6,
ATSC_AC3_CHANNELS_3_2 = 0x7,
ATSC_AC3_CHANNELS_1 = 0x8,
ATSC_AC3_CHANNELS_LTEQ_2 = 0x9,
ATSC_AC3_CHANNELS_LTEQ_3 = 0xa,
ATSC_AC3_CHANNELS_LTEQ_4 = 0xb,
ATSC_AC3_CHANNELS_LTEQ_5 = 0xc,
ATSC_AC3_CHANNELS_LTEQ_6 = 0xd,
};
/**
* atsc_ac3_descriptor structure.
*/
struct atsc_ac3_descriptor {
struct descriptor d;
EBIT2(uint8_t sample_rate_code : 3; ,
uint8_t bsid : 5; );
EBIT2(uint8_t bit_rate_code : 6; ,
uint8_t surround_mode : 2; );
EBIT3(uint8_t bsmod : 3; ,
uint8_t num_channels : 4; ,
uint8_t full_svc : 1; );
/* uint8_t additional_info[] */
} __ucsi_packed;
/**
* Process an atsc_ac3_descriptor.
*
* @param d Generic descriptor structure.
* @return atsc_ac3_descriptor pointer, or NULL on error.
*/
static inline struct atsc_ac3_descriptor*
atsc_ac3_descriptor_codec(struct descriptor* d)
{
int pos = 0;
if (d->len < (pos+4))
return NULL;
pos += 4;
return (struct atsc_ac3_descriptor*) d;
}
/**
* Retrieve pointer to additional_info field of a atsc_ac3_descriptor.
*
* @param d atsc_ac3_descriptor pointer.
* @return Pointer to additional_info field.
*/
static inline uint8_t *atsc_ac3_descriptor_additional_info(struct atsc_ac3_descriptor *d)
{
int pos = sizeof(struct atsc_ac3_descriptor);
return ((uint8_t *) d) + pos;
}
/**
* Determine length of additional_info field of a atsc_ac3_descriptor.
*
* @param d atsc_ac3_descriptor pointer.
* @return Length of field in bytes.
*/
static inline int atsc_ac3_descriptor_additional_info_length(struct atsc_ac3_descriptor* d)
{
return d->d.len - 3;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,743 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "libucsi/endianops.h"
#include "libucsi/atsc/types.h"
#define HUFFTREE_LITERAL_MASK 0x80
#define HUFFSTRING_END 0x00
#define HUFFSTRING_ESCAPE 0x1b
#define DEST_ALLOC_DELTA 20
struct hufftree_entry {
uint8_t left_idx;
uint8_t right_idx;
} __ucsi_packed;
struct huffbuff {
uint8_t *buf;
uint32_t buf_len;
uint32_t cur_byte;
uint8_t cur_bit;
};
static struct hufftree_entry program_description_hufftree[][128] = {
{ {0x14, 0x15}, {0x9b, 0xd6}, {0xc9, 0xcf}, {0xd7, 0xc7}, {0x01, 0xa2},
{0xce, 0xcb}, {0x02, 0x03}, {0xc5, 0xcc}, {0xc6, 0xc8}, {0x04, 0xc4},
{0x05, 0xc2}, {0x06, 0xc3}, {0xd2, 0x07}, {0xd3, 0x08}, {0xca, 0xd4},
{0x09, 0xcd}, {0xd0, 0x0a}, {0xc1, 0x0b}, {0x0c, 0x0d}, {0x0e, 0x0f},
{0x10, 0x11}, {0x12, 0x13}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x38, 0x39}, {0xad, 0xaf}, {0xb7, 0xda}, {0xa8, 0xb3}, {0xb5, 0x01},
{0x02, 0x9b}, {0xb4, 0xf1}, {0xa2, 0xd5}, {0xd6, 0xd9}, {0x03, 0x04},
{0x05, 0xcf}, {0x06, 0xc9}, {0xf9, 0xea}, {0xeb, 0xf5}, {0xf6, 0x07},
{0x08, 0x09}, {0xb2, 0xc5}, {0xc6, 0xb1}, {0x0a, 0xee}, {0xcb, 0x0b},
{0xd4, 0x0c}, {0xc4, 0xc8}, {0xd2, 0x0d}, {0x0e, 0x0f}, {0xc7, 0xca},
{0xce, 0xd0}, {0xd7, 0x10}, {0xc2, 0x11}, {0xcc, 0xec}, {0xe5, 0xe7},
{0x12, 0xcd}, {0x13, 0x14}, {0xc3, 0x15}, {0x16, 0x17}, {0xed, 0x18},
{0x19, 0xf2}, {0x1a, 0xd3}, {0x1b, 0x1c}, {0xe4, 0x1d}, {0xc1, 0xe3},
{0x1e, 0xe9}, {0xf0, 0xe2}, {0xf7, 0x1f}, {0xf3, 0xe6}, {0x20, 0x21},
{0x22, 0xe8}, {0xef, 0x23}, {0x24, 0x25}, {0x26, 0x27}, {0x28, 0x29},
{0x2a, 0xf4}, {0x2b, 0x2c}, {0x2d, 0x2e}, {0x2f, 0xe1}, {0x30, 0x31},
{0x32, 0x33}, {0x34, 0x35}, {0x36, 0x37}, },
{ {0x9b, 0x9b}, },
{ {0x03, 0x04}, {0x80, 0xae}, {0xc8, 0xd4}, {0x01, 0x02}, {0x9b, 0xa0}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x02, 0xf3}, {0xa0, 0xf4}, {0x9b, 0x01}, },
{ {0x9b, 0x9b}, },
{ {0xac, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x01, 0xa0}, {0x9b, 0xa2}, },
{ {0x07, 0x08}, {0xe2, 0xe4}, {0xe5, 0xe6}, {0xa0, 0xf2}, {0xe1, 0x01},
{0x02, 0xf3}, {0xe3, 0x03}, {0x04, 0x05}, {0x9b, 0x06}, },
{ {0x04, 0x80}, {0xca, 0xd3}, {0xa2, 0x01}, {0x9b, 0x02}, {0x03, 0xa0}, },
{ {0x9b, 0xa0}, },
{ {0x03, 0x04}, {0x9b, 0xb7}, {0xf4, 0xa0}, {0xb0, 0xf3}, {0x01, 0x02}, },
{ {0xb9, 0x02}, {0xb8, 0x9b}, {0xa0, 0x01}, },
{ {0xae, 0x02}, {0xb6, 0x9b}, {0x01, 0xa0}, },
{ {0xa0, 0x01}, {0x9b, 0xb0}, },
{ {0xae, 0x01}, {0x9b, 0xa0}, },
{ {0xae, 0x01}, {0xa0, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x01}, {0xac, 0xae}, },
{ {0x9b, 0x9b}, },
{ {0x02, 0x03}, {0x9b, 0xa0}, {0xb5, 0xb6}, {0xb8, 0x01}, },
{ {0x9b, 0xa0}, },
{ {0x9b, 0xa0}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0xa0}, },
{ {0x9b, 0x9b}, },
{ {0x08, 0x09}, {0xe6, 0xf5}, {0xf3, 0xf4}, {0x9b, 0xe4}, {0x01, 0xed},
{0x02, 0x03}, {0x04, 0xf2}, {0x05, 0x06}, {0xec, 0xee}, {0x07, 0xa0}, },
{ {0x05, 0x06}, {0x9b, 0xec}, {0xf5, 0x01}, {0x02, 0xe1}, {0xef, 0xe5},
{0xe9, 0xf2}, {0x03, 0x04}, },
{ {0x06, 0x07}, {0x9b, 0xe9}, {0xf9, 0xf2}, {0xf5, 0x01}, {0x02, 0x03},
{0xec, 0xef}, {0xe1, 0x04}, {0xe8, 0x05}, },
{ {0x05, 0x06}, {0xf9, 0xf2}, {0xf5, 0x9b}, {0xe5, 0xef}, {0x01, 0x02},
{0xe9, 0xe1}, {0x03, 0x04}, },
{ {0x06, 0x07}, {0xe1, 0xe9}, {0xee, 0xf6}, {0xe4, 0xec}, {0xf3, 0x01},
{0x02, 0xf2}, {0x03, 0x04}, {0x9b, 0x05}, },
{ {0x02, 0x03}, {0xe5, 0xec}, {0x9b, 0xef}, {0x01, 0xf2}, },
{ {0x05, 0x06}, {0xf5, 0xef}, {0x9b, 0xec}, {0xe9, 0x01}, {0xe1, 0xf2},
{0x02, 0xe5}, {0x03, 0x04}, },
{ {0x03, 0x04}, {0x9b, 0xe5}, {0xe9, 0xf5}, {0xe1, 0x01}, {0xef, 0x02}, },
{ {0x04, 0x05}, {0xa0, 0xc9}, {0xf3, 0x9b}, {0xae, 0xf2}, {0x01, 0x02},
{0x03, 0xee}, },
{ {0xef, 0x05}, {0x9b, 0xae}, {0xe9, 0xe5}, {0x01, 0xf5}, {0x02, 0xe1},
{0x03, 0x04}, },
{ {0xe5, 0x03}, {0xe1, 0xe9}, {0xf2, 0x9b}, {0x01, 0x02}, },
{ {0x03, 0x04}, {0x9b, 0xe9}, {0xf5, 0x01}, {0xe5, 0x02}, {0xef, 0xe1}, },
{ {0xe1, 0x05}, {0x9b, 0xe3}, {0xef, 0x01}, {0xf5, 0xe5}, {0x02, 0x03},
{0xe9, 0x04}, },
{ {0xe5, 0x03}, {0x9b, 0xe9}, {0x01, 0xe1}, {0xef, 0x02}, },
{ {0x03, 0x04}, {0xa7, 0xee}, {0xec, 0xf2}, {0xf3, 0x01}, {0x9b, 0x02}, },
{ {0xe1, 0x06}, {0x9b, 0xe8}, {0xe9, 0x01}, {0xf2, 0xec}, {0x02, 0xef},
{0x03, 0xe5}, {0x04, 0x05}, },
{ {0x9b, 0x9b}, },
{ {0x03, 0x04}, {0x9b, 0xae}, {0x01, 0xe9}, {0x02, 0xe1}, {0xe5, 0xef}, },
{ {0x09, 0x0a}, {0xf6, 0xf9}, {0x01, 0xae}, {0xe3, 0xe9}, {0xf5, 0x9b},
{0xe5, 0xef}, {0x02, 0x03}, {0xe1, 0x04}, {0xe8, 0x05}, {0x06, 0xf4},
{0x07, 0x08}, },
{ {0xe8, 0x07}, {0xe5, 0xf7}, {0xd6, 0xe1}, {0x9b, 0xe9}, {0xf2, 0x01},
{0x02, 0x03}, {0x04, 0xef}, {0x05, 0x06}, },
{ {0xae, 0x01}, {0x9b, 0xee}, },
{ {0xe9, 0x02}, {0xe5, 0x9b}, {0xa0, 0x01}, },
{ {0x03, 0x04}, {0x9b, 0xe8}, {0xe5, 0xe1}, {0xef, 0x01}, {0xe9, 0x02}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0xef}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x18, 0x19}, {0xe8, 0xef}, {0xf8, 0x9b}, {0xa7, 0xf7}, {0xfa, 0x01},
{0x02, 0x03}, {0x04, 0xe5}, {0xae, 0x05}, {0xe6, 0xe2}, {0x06, 0xf6},
{0xeb, 0xf5}, {0xe9, 0x07}, {0xf0, 0xf9}, {0xe7, 0x08}, {0x09, 0xe4},
{0x0a, 0xe3}, {0x0b, 0xed}, {0x0c, 0xf3}, {0x0d, 0x0e}, {0x0f, 0xec},
{0x10, 0xf4}, {0x11, 0x12}, {0xf2, 0xa0}, {0x13, 0x14}, {0x15, 0xee},
{0x16, 0x17}, },
{ {0x0b, 0x0c}, {0xe4, 0xf3}, {0x9b, 0xae}, {0xe2, 0x01}, {0x02, 0x03},
{0xec, 0xa0}, {0x04, 0xe9}, {0xf2, 0xf5}, {0x05, 0xf9}, {0xe1, 0x06},
{0xef, 0x07}, {0xe5, 0x08}, {0x09, 0x0a}, },
{ {0x0f, 0x10}, {0xf1, 0xae}, {0xc4, 0xf9}, {0xac, 0x01}, {0xe3, 0x02},
{0x9b, 0xf2}, {0x03, 0x04}, {0xa0, 0xec}, {0xf5, 0x05}, {0x06, 0xe9},
{0x07, 0xeb}, {0x08, 0xf4}, {0x09, 0xe5}, {0x0a, 0xef}, {0xe1, 0xe8},
{0x0b, 0x0c}, {0x0d, 0x0e}, },
{ {0x13, 0x14}, {0xa7, 0xbb}, {0xe6, 0xed}, {0xf7, 0xe7}, {0xf6, 0x01},
{0x02, 0x9b}, {0xee, 0x03}, {0x04, 0xec}, {0x05, 0xf5}, {0x06, 0xac},
{0xe4, 0xf9}, {0xf2, 0x07}, {0x08, 0x09}, {0xae, 0x0a}, {0xef, 0x0b},
{0xe1, 0xf3}, {0x0c, 0xe9}, {0x0d, 0x0e}, {0x0f, 0x10}, {0xe5, 0x11},
{0x12, 0xa0}, },
{ {0x1d, 0x1e}, {0xa9, 0xe8}, {0xf5, 0x9b}, {0x01, 0xad}, {0xbb, 0xeb},
{0xfa, 0x02}, {0xa7, 0xe6}, {0xe2, 0xe7}, {0x03, 0x04}, {0x05, 0x06},
{0xe9, 0xf8}, {0x07, 0xac}, {0xef, 0xf0}, {0x08, 0xed}, {0xf6, 0xf9},
{0x09, 0xf7}, {0x0a, 0x0b}, {0xae, 0x0c}, {0xe3, 0x0d}, {0xe5, 0xf4},
{0x0e, 0x0f}, {0xe4, 0x10}, {0xec, 0x11}, {0xe1, 0x12}, {0x13, 0x14},
{0x15, 0x16}, {0xee, 0xf3}, {0x17, 0x18}, {0xf2, 0xa0}, {0x19, 0x1a},
{0x1b, 0x1c}, },
{ {0x09, 0x0a}, {0xae, 0x9b}, {0xec, 0x01}, {0xf5, 0x02}, {0xf4, 0xe6},
{0x03, 0xe1}, {0xe5, 0xe9}, {0x04, 0xf2}, {0xef, 0x05}, {0x06, 0x07},
{0xa0, 0x08}, },
{ {0x0e, 0x0f}, {0xad, 0xe7}, {0x9b, 0xa7}, {0xf9, 0x01}, {0xec, 0x02},
{0xac, 0xf2}, {0x03, 0xae}, {0xf3, 0xf5}, {0x04, 0x05}, {0xef, 0x06},
{0x07, 0xe9}, {0xe1, 0x08}, {0x09, 0xe8}, {0x0a, 0x0b}, {0xe5, 0x0c},
{0xa0, 0x0d}, },
{ {0x0d, 0x0e}, {0xa7, 0xac}, {0xf3, 0xad}, {0x01, 0x02}, {0x9b, 0xf9},
{0xf5, 0xae}, {0x03, 0xee}, {0x04, 0xf2}, {0x05, 0x06}, {0xf4, 0x07},
{0x08, 0x09}, {0xef, 0xe1}, {0xa0, 0x0a}, {0xe9, 0x0b}, {0x0c, 0xe5}, },
{ {0x14, 0x15}, {0xac, 0xe2}, {0xf8, 0x9b}, {0xae, 0xfa}, {0x01, 0xeb},
{0x02, 0xa0}, {0x03, 0x04}, {0xf0, 0x05}, {0x06, 0xe6}, {0xf6, 0x07},
{0xe4, 0xed}, {0xe7, 0x08}, {0xe1, 0xef}, {0xf2, 0x09}, {0x0a, 0x0b},
{0xec, 0x0c}, {0xe5, 0xe3}, {0x0d, 0xf4}, {0x0e, 0xf3}, {0x0f, 0x10},
{0x11, 0xee}, {0x12, 0x13}, },
{ {0x03, 0xef}, {0x9b, 0xe1}, {0xe5, 0xf5}, {0x01, 0x02}, },
{ {0x08, 0x09}, {0xec, 0xf9}, {0xa7, 0xee}, {0x01, 0xac}, {0x9b, 0xae},
{0x02, 0x03}, {0x04, 0xf3}, {0x05, 0xe9}, {0x06, 0xa0}, {0x07, 0xe5}, },
{ {0x16, 0x17}, {0xa7, 0xad}, {0xee, 0xe3}, {0xeb, 0xf2}, {0x9b, 0xe2},
{0x01, 0x02}, {0xf5, 0x03}, {0xf4, 0xac}, {0x04, 0x05}, {0xe6, 0xed},
{0xf6, 0x06}, {0xae, 0xf0}, {0x07, 0x08}, {0xf3, 0x09}, {0x0a, 0xe4},
{0x0b, 0x0c}, {0xf9, 0x0d}, {0xef, 0x0e}, {0xe1, 0x0f}, {0x10, 0xe9},
{0xec, 0x11}, {0xa0, 0xe5}, {0x12, 0x13}, {0x14, 0x15}, },
{ {0x0c, 0x0d}, {0xa7, 0xbb}, {0x9b, 0x01}, {0xf9, 0xae}, {0xe2, 0x02},
{0xed, 0xf3}, {0x03, 0xf5}, {0xef, 0xf0}, {0x04, 0x05}, {0xe9, 0x06},
{0x07, 0x08}, {0x09, 0xa0}, {0xe1, 0xe5}, {0x0a, 0x0b}, },
{ {0x19, 0x1a}, {0xad, 0xbb}, {0xe2, 0xea}, {0xed, 0xf2}, {0xfa, 0xe6},
{0xec, 0x01}, {0x02, 0x03}, {0x9b, 0xf5}, {0x04, 0xa7}, {0xf6, 0xf9},
{0x05, 0x06}, {0xeb, 0xef}, {0x07, 0x08}, {0x09, 0x0a}, {0xac, 0x0b},
{0x0c, 0xe3}, {0xae, 0x0d}, {0xee, 0xe9}, {0x0e, 0xe1}, {0x0f, 0xf3},
{0x10, 0x11}, {0xf4, 0x12}, {0xe7, 0xe5}, {0x13, 0x14}, {0xe4, 0x15},
{0x16, 0x17}, {0xa0, 0x18}, },
{ {0x1a, 0x1b}, {0xc2, 0x9b}, {0xad, 0xac}, {0xf8, 0x01}, {0xae, 0x02},
{0x03, 0xe5}, {0xe7, 0xe8}, {0xf9, 0xe9}, {0xeb, 0x04}, {0xe3, 0xe1},
{0x05, 0xf6}, {0x06, 0xe4}, {0x07, 0xe2}, {0xf0, 0x08}, {0x09, 0xf3},
{0xf4, 0xf7}, {0xef, 0x0a}, {0x0b, 0x0c}, {0x0d, 0xec}, {0x0e, 0x0f},
{0x10, 0xf5}, {0xed, 0x11}, {0xe6, 0xa0}, {0x12, 0xf2}, {0x13, 0x14},
{0x15, 0xee}, {0x16, 0x17}, {0x18, 0x19}, },
{ {0x0e, 0x0f}, {0xad, 0xed}, {0xf9, 0x9b}, {0xae, 0x01}, {0xf3, 0x02},
{0x03, 0xf5}, {0xf4, 0xf0}, {0x04, 0xef}, {0x05, 0xe9}, {0x06, 0xe8},
{0xa0, 0xe1}, {0xec, 0x07}, {0xf2, 0x08}, {0xe5, 0x09}, {0x0a, 0x0b},
{0x0c, 0x0d}, },
{ {0x9b, 0xf5}, },
{ {0x19, 0x1a}, {0xa9, 0xbb}, {0xf6, 0xe6}, {0x01, 0x9b}, {0xad, 0xe2},
{0xf0, 0x02}, {0xa7, 0x03}, {0x04, 0x05}, {0xf5, 0xe3}, {0xac, 0xe7},
{0xf2, 0x06}, {0xeb, 0x07}, {0xec, 0xed}, {0xee, 0xf9}, {0x08, 0xae},
{0x09, 0x0a}, {0xe4, 0x0b}, {0x0c, 0xf4}, {0x0d, 0xf3}, {0x0e, 0x0f},
{0x10, 0xe1}, {0xef, 0x11}, {0xe9, 0x12}, {0x13, 0xe5}, {0x14, 0xa0},
{0x15, 0x16}, {0x17, 0x18}, },
{ {0xa0, 0x16}, {0xa2, 0xa7}, {0xe2, 0xeb}, {0xed, 0xee}, {0x9b, 0xf7},
{0x01, 0x02}, {0x03, 0xbb}, {0xf9, 0xf0}, {0x04, 0x05}, {0xec, 0x06},
{0x07, 0x08}, {0xf5, 0xe1}, {0x09, 0xac}, {0xe3, 0x0a}, {0xe8, 0x0b},
{0xe9, 0x0c}, {0xef, 0xf3}, {0xae, 0x0d}, {0x0e, 0xe5}, {0x0f, 0x10},
{0x11, 0xf4}, {0x12, 0x13}, {0x14, 0x15}, },
{ {0x14, 0x15}, {0xbb, 0xe2}, {0xad, 0xed}, {0x01, 0x9b}, {0xa7, 0xe3},
{0xac, 0xec}, {0xee, 0x02}, {0xf7, 0x03}, {0x04, 0xf9}, {0x05, 0x06},
{0x07, 0x08}, {0xf4, 0xae}, {0xf5, 0x09}, {0x0a, 0xf2}, {0xe1, 0xf3},
{0x0b, 0x0c}, {0x0d, 0xe9}, {0x0e, 0x0f}, {0xef, 0xe5}, {0x10, 0xa0},
{0xe8, 0x11}, {0x12, 0x13}, },
{ {0x11, 0x12}, {0xef, 0xf6}, {0x9b, 0xeb}, {0xf9, 0x01}, {0xa0, 0xe2},
{0x02, 0xe1}, {0x03, 0xed}, {0x04, 0xe3}, {0xe9, 0x05}, {0xe4, 0xe5},
{0xe7, 0x06}, {0xec, 0xf0}, {0x07, 0x08}, {0x09, 0x0a}, {0x0b, 0xf3},
{0x0c, 0xf4}, {0xee, 0x0d}, {0xf2, 0x0e}, {0x0f, 0x10}, },
{ {0x05, 0xe5}, {0xf3, 0xf9}, {0x9b, 0x01}, {0xef, 0x02}, {0x03, 0xe1},
{0x04, 0xe9}, },
{ {0x0a, 0x0b}, {0xae, 0x9b}, {0xec, 0xed}, {0x01, 0x02}, {0xf3, 0xee},
{0xf2, 0x03}, {0xe5, 0x04}, {0xe8, 0xa0}, {0xe1, 0x05}, {0xef, 0x06},
{0x07, 0x08}, {0xe9, 0x09}, },
{ {0x05, 0x06}, {0xa0, 0xac}, {0xad, 0xf4}, {0xe9, 0x01}, {0x02, 0xe1},
{0xe5, 0x03}, {0x9b, 0x04}, },
{ {0x11, 0xa0}, {0xbf, 0xe1}, {0xe2, 0xe6}, {0xed, 0xe4}, {0xe9, 0xf7},
{0xa7, 0x01}, {0x02, 0xbb}, {0x03, 0x04}, {0xec, 0x05}, {0x9b, 0xee},
{0x06, 0xef}, {0x07, 0xac}, {0xe5, 0xf3}, {0x08, 0x09}, {0x0a, 0xae},
{0x0b, 0x0c}, {0x0d, 0x0e}, {0x0f, 0x10}, },
{ {0x06, 0x07}, {0xa0, 0xae}, {0xe1, 0xe5}, {0xec, 0xfa}, {0x9b, 0xef},
{0xe9, 0x01}, {0x02, 0x03}, {0x04, 0x05}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
};
static struct hufftree_entry program_title_hufftree[][128] = {
{ {0x1b, 0x1c}, {0xb4, 0xa4}, {0xb2, 0xb7}, {0xda, 0x01}, {0xd1, 0x02},
{0x03, 0x9b}, {0x04, 0xd5}, {0xd9, 0x05}, {0xcb, 0xd6}, {0x06, 0xcf},
{0x07, 0x08}, {0xca, 0x09}, {0xc9, 0xc5}, {0xc6, 0x0a}, {0xd2, 0xc4},
{0xc7, 0xcc}, {0xd0, 0xc8}, {0xd7, 0xce}, {0x0b, 0xc1}, {0x0c, 0xc2},
{0xcd, 0xc3}, {0x0d, 0x0e}, {0x0f, 0x10}, {0xd3, 0x11}, {0xd4, 0x12},
{0x13, 0x14}, {0x15, 0x16}, {0x17, 0x18}, {0x19, 0x1a}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x29, 0x2a}, {0xd8, 0xe5}, {0xb9, 0x01}, {0xa7, 0xb1}, {0xec, 0xd1},
{0x02, 0xad}, {0xb2, 0xda}, {0xe3, 0xb3}, {0x03, 0xe4}, {0xe6, 0x04},
{0x9b, 0xe2}, {0x05, 0x06}, {0x07, 0x08}, {0x09, 0xd5}, {0x0a, 0xd6},
{0x0b, 0xd9}, {0x0c, 0xa6}, {0xe9, 0xcb}, {0xc5, 0xcf}, {0x0d, 0x0e},
{0xca, 0xc9}, {0x0f, 0xc7}, {0x10, 0x11}, {0xe1, 0x12}, {0x13, 0xc6},
{0xd2, 0xc8}, {0xce, 0xc1}, {0xc4, 0xd0}, {0xcc, 0x14}, {0x15, 0xef},
{0xc2, 0xd7}, {0x16, 0xcd}, {0x17, 0xf4}, {0xd4, 0x18}, {0x19, 0x1a},
{0xc3, 0xd3}, {0x1b, 0x1c}, {0x1d, 0x1e}, {0x1f, 0x20}, {0x21, 0x22},
{0x23, 0x24}, {0x25, 0x26}, {0x27, 0x28}, },
{ {0x01, 0x80}, {0xa0, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0xb1, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0xa0}, },
{ {0x04, 0xf3}, {0xe4, 0xb9}, {0x01, 0xf4}, {0xa0, 0x9b}, {0x02, 0x03}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x01, 0x02}, {0x9b, 0xc1}, {0xc8, 0xd3}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0xa0}, },
{ {0x07, 0x08}, {0xb1, 0xd2}, {0xd3, 0xd4}, {0xd5, 0xad}, {0xcd, 0xc1},
{0x01, 0x02}, {0x03, 0xa0}, {0x04, 0x9b}, {0x05, 0x06}, },
{ {0xa0, 0x05}, {0xc9, 0xd7}, {0xd3, 0x01}, {0x02, 0x9b}, {0xae, 0x80},
{0x03, 0x04}, },
{ {0x9b, 0x9b}, },
{ {0x02, 0x03}, {0xad, 0x9b}, {0x01, 0x80}, {0xa0, 0xb0}, },
{ {0x04, 0x05}, {0x80, 0x9b}, {0xb1, 0xb2}, {0xa0, 0xb0}, {0xb9, 0x01},
{0x02, 0x03}, },
{ {0x02, 0x03}, {0xb1, 0xba}, {0x01, 0xb0}, {0x9b, 0x80}, },
{ {0x80, 0x01}, {0xb0, 0x9b}, },
{ {0x9b, 0xb8}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0xb0}, },
{ {0x9b, 0xa0}, },
{ {0x02, 0x03}, {0xb1, 0xb3}, {0xb9, 0xb0}, {0x01, 0x9b}, },
{ {0x9b, 0xa0}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x80}, },
{ {0x9b, 0x9b}, },
{ {0x13, 0x14}, {0xaa, 0xad}, {0xae, 0xf6}, {0xe7, 0xf4}, {0xe2, 0xe9},
{0x01, 0x02}, {0xc2, 0xf0}, {0x9b, 0xf3}, {0xe3, 0xe6}, {0xf7, 0x03},
{0xf5, 0x04}, {0x05, 0x06}, {0xf2, 0x07}, {0x08, 0x09}, {0x0a, 0x0b},
{0x0c, 0xe4}, {0xa0, 0x0d}, {0xec, 0xee}, {0x0e, 0xed}, {0x0f, 0x10},
{0x11, 0x12}, },
{ {0x08, 0x09}, {0xc1, 0xd3}, {0x9b, 0x01}, {0xc3, 0x02}, {0xe9, 0xec},
{0x03, 0xf2}, {0xf5, 0x04}, {0xef, 0xe1}, {0x05, 0xe5}, {0x06, 0x07}, },
{ {0x0b, 0x0c}, {0xc1, 0xf9}, {0x01, 0xc2}, {0xcf, 0xe5}, {0xf5, 0x9b},
{0xe9, 0x02}, {0xa0, 0x03}, {0x04, 0x05}, {0xf2, 0x06}, {0xec, 0x07},
{0xe1, 0x08}, {0x09, 0xe8}, {0x0a, 0xef}, },
{ {0x05, 0x06}, {0xf9, 0x9b}, {0x01, 0xf5}, {0x02, 0xf2}, {0xe9, 0xe5},
{0xef, 0x03}, {0xe1, 0x04}, },
{ {0x0a, 0x0b}, {0xf1, 0xf5}, {0xf3, 0x01}, {0xed, 0xf9}, {0xc3, 0x02},
{0xec, 0xee}, {0xe4, 0xf8}, {0x03, 0x9b}, {0xf6, 0x04}, {0x05, 0xe1},
{0x06, 0x07}, {0x08, 0x09}, },
{ {0x07, 0x08}, {0xa0, 0x9b}, {0xcc, 0x01}, {0xe5, 0x02}, {0xec, 0xf5},
{0xef, 0x03}, {0xe9, 0xf2}, {0x04, 0x05}, {0xe1, 0x06}, },
{ {0x09, 0x0a}, {0xae, 0xec}, {0xf9, 0xc1}, {0xe8, 0x01}, {0x9b, 0x02},
{0x03, 0x04}, {0xe1, 0xf5}, {0xe9, 0x05}, {0xe5, 0x06}, {0xf2, 0xef},
{0x07, 0x08}, },
{ {0xef, 0x05}, {0x80, 0x9b}, {0xf5, 0x01}, {0x02, 0xe9}, {0xe1, 0x03},
{0xe5, 0x04}, },
{ {0xee, 0x0b}, {0xba, 0xd4}, {0xae, 0xf2}, {0xe3, 0x01}, {0xa0, 0x02},
{0x80, 0x9b}, {0xed, 0x03}, {0xc9, 0xf3}, {0xf4, 0x04}, {0x05, 0x06},
{0x07, 0x08}, {0x09, 0x0a}, },
{ {0x02, 0x03}, {0x9b, 0xf5}, {0x01, 0xe1}, {0xef, 0xe5}, },
{ {0x05, 0xe9}, {0xe1, 0xef}, {0xf5, 0xee}, {0x9b, 0xe5}, {0x01, 0x02},
{0x03, 0x04}, },
{ {0x04, 0x05}, {0xa0, 0x9b}, {0x01, 0xf5}, {0x02, 0xe5}, {0xef, 0x03},
{0xe1, 0xe9}, },
{ {0x08, 0x09}, {0xaa, 0xd4}, {0x01, 0x9b}, {0xe3, 0x02}, {0xf2, 0x03},
{0xe5, 0x04}, {0xf5, 0xf9}, {0xe9, 0x05}, {0xef, 0x06}, {0x07, 0xe1}, },
{ {0xe5, 0x08}, {0xce, 0xa0}, {0xc6, 0xf5}, {0x01, 0x02}, {0x9b, 0xc2},
{0x03, 0xe1}, {0x04, 0xef}, {0x05, 0xe9}, {0x06, 0x07}, },
{ {0x09, 0x0a}, {0xe4, 0xf3}, {0xe6, 0xf6}, {0xf7, 0xf0}, {0xf2, 0x01},
{0xec, 0x02}, {0x03, 0xa0}, {0x9b, 0x04}, {0x05, 0xf5}, {0x06, 0x07},
{0xee, 0x08}, },
{ {0x0b, 0x0c}, {0xa0, 0xf3}, {0xf9, 0xae}, {0xd2, 0xc7}, {0x01, 0x9b},
{0x02, 0xf5}, {0x03, 0x04}, {0x05, 0xe9}, {0xec, 0x06}, {0xe5, 0x07},
{0xef, 0x08}, {0xe1, 0x09}, {0xf2, 0x0a}, },
{ {0x01, 0xf5}, {0x9b, 0xd6}, },
{ {0x04, 0x05}, {0xe8, 0x9b}, {0x01, 0xf5}, {0x02, 0xe1}, {0xe9, 0xef},
{0x03, 0xe5}, },
{ {0x10, 0x11}, {0xaa, 0xec}, {0xf1, 0xae}, {0xa0, 0xf7}, {0xed, 0xee},
{0x01, 0x02}, {0x9b, 0xeb}, {0x03, 0x04}, {0x05, 0x06}, {0xe3, 0x07},
{0xef, 0x08}, {0xe9, 0xf5}, {0x09, 0xe1}, {0xe5, 0xf0}, {0xe8, 0x0a},
{0x0b, 0x0c}, {0x0d, 0xf4}, {0x0e, 0x0f}, },
{ {0xe8, 0x0a}, {0xad, 0xce}, {0x9b, 0x01}, {0xd6, 0x02}, {0xf5, 0xf7},
{0x03, 0x04}, {0xe1, 0xe5}, {0xe9, 0x05}, {0xf2, 0x06}, {0xef, 0x07},
{0x08, 0x09}, },
{ {0xee, 0x03}, {0xec, 0xae}, {0x01, 0x9b}, {0x02, 0xf0}, },
{ {0x06, 0xe9}, {0xa0, 0xc3}, {0xef, 0x9b}, {0xe5, 0x01}, {0x80, 0x02},
{0x03, 0xe1}, {0x04, 0x05}, },
{ {0x06, 0x07}, {0xc6, 0xd7}, {0x01, 0x9b}, {0xf2, 0x02}, {0x03, 0xe8},
{0xe5, 0xe1}, {0x04, 0xe9}, {0xef, 0x05}, },
{ {0x9b, 0x9b}, },
{ {0x02, 0xef}, {0xe1, 0x9b}, {0x01, 0xe5}, },
{ {0x01, 0xef}, {0x9b, 0xe1}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x19, 0x1a}, {0x9b, 0xba}, {0xe5, 0xea}, {0xf8, 0x01}, {0x02, 0xe6},
{0xa7, 0x03}, {0xfa, 0xe8}, {0x04, 0xf7}, {0x05, 0xf5}, {0xe2, 0x06},
{0xeb, 0x07}, {0xf0, 0x08}, {0x80, 0xf6}, {0xe7, 0x09}, {0xe4, 0x0a},
{0xa0, 0xe9}, {0x0b, 0xe3}, {0xf9, 0x0c}, {0x0d, 0xed}, {0x0e, 0x0f},
{0xf3, 0x10}, {0x11, 0xec}, {0x12, 0xf4}, {0xf2, 0x13}, {0xee, 0x14},
{0x15, 0x16}, {0x17, 0x18}, },
{ {0x0a, 0x0b}, {0xf3, 0x9b}, {0xf5, 0xe2}, {0x01, 0x80}, {0xa0, 0x02},
{0xe5, 0xf2}, {0xe9, 0x03}, {0xec, 0x04}, {0xf9, 0x05}, {0xef, 0x06},
{0xe1, 0x07}, {0x08, 0x09}, },
{ {0x10, 0x11}, {0xc3, 0xcc}, {0xc7, 0x9b}, {0xe3, 0x01}, {0x80, 0xec},
{0xf9, 0x02}, {0xf3, 0x03}, {0xf5, 0x04}, {0x05, 0xf2}, {0x06, 0xe9},
{0xa0, 0x07}, {0x08, 0xef}, {0xf4, 0x09}, {0x0a, 0xe1}, {0x0b, 0xe8},
{0xeb, 0xe5}, {0x0c, 0x0d}, {0x0e, 0x0f}, },
{ {0x0e, 0x0f}, {0xae, 0xf5}, {0xf7, 0x01}, {0xec, 0x02}, {0xe4, 0xe7},
{0xf2, 0x03}, {0x9b, 0xef}, {0x04, 0xf6}, {0x05, 0x06}, {0xf9, 0xf3},
{0x07, 0xe9}, {0xe1, 0x08}, {0x09, 0x80}, {0x0a, 0x0b}, {0xe5, 0x0c},
{0x0d, 0xa0}, },
{ {0x1e, 0x1f}, {0x9b, 0xa1}, {0xad, 0xe8}, {0xea, 0xf1}, {0xf5, 0xfa},
{0x01, 0x02}, {0x03, 0x04}, {0xba, 0xf8}, {0xa7, 0xe2}, {0xe9, 0x05},
{0x06, 0x07}, {0xe6, 0xed}, {0xe7, 0xeb}, {0x08, 0x09}, {0xf6, 0xf0},
{0x0a, 0xef}, {0x0b, 0xe3}, {0x0c, 0x0d}, {0x0e, 0xf9}, {0x0f, 0xe4},
{0xec, 0x10}, {0xe5, 0x11}, {0xf4, 0xf7}, {0x12, 0x13}, {0xe1, 0x14},
{0x15, 0x16}, {0xee, 0xf3}, {0x17, 0x80}, {0x18, 0x19}, {0xf2, 0x1a},
{0x1b, 0xa0}, {0x1c, 0x1d}, },
{ {0xa0, 0x0b}, {0xf5, 0x9b}, {0x01, 0xec}, {0xf3, 0xf2}, {0x80, 0xe1},
{0x02, 0x03}, {0xf4, 0xe9}, {0xef, 0xe6}, {0x04, 0x05}, {0x06, 0x07},
{0xe5, 0x08}, {0x09, 0x0a}, },
{ {0x0f, 0x10}, {0xba, 0xf9}, {0xa7, 0xf4}, {0x9b, 0x01}, {0xe7, 0xec},
{0x02, 0xee}, {0x03, 0xef}, {0xf5, 0x04}, {0xf2, 0x05}, {0x06, 0xe9},
{0x07, 0xf3}, {0xe1, 0x08}, {0x09, 0x0a}, {0x0b, 0xe5}, {0x80, 0x0c},
{0xe8, 0xa0}, {0x0d, 0x0e}, },
{ {0xe5, 0x0d}, {0xe2, 0xf5}, {0xf7, 0x9b}, {0xec, 0x01}, {0xf9, 0xee},
{0x02, 0x03}, {0x04, 0xf2}, {0x05, 0x80}, {0x06, 0xa0}, {0xe1, 0xef},
{0x07, 0xf4}, {0xe9, 0x08}, {0x09, 0x0a}, {0x0b, 0x0c}, },
{ {0x15, 0x16}, {0xa1, 0xf8}, {0xe9, 0xeb}, {0x01, 0x80}, {0x9b, 0xfa},
{0xe2, 0x02}, {0x03, 0x04}, {0xa0, 0xf0}, {0x05, 0x06}, {0x07, 0xe1},
{0x08, 0xe6}, {0xf2, 0xed}, {0xf6, 0x09}, {0xe4, 0x0a}, {0xef, 0xf4},
{0xec, 0xf3}, {0xe7, 0xe5}, {0x0b, 0xe3}, {0x0c, 0x0d}, {0x0e, 0x0f},
{0x10, 0x11}, {0x12, 0x13}, {0xee, 0x14}, },
{ {0xef, 0x01}, {0x9b, 0xe1}, },
{ {0x0b, 0x0c}, {0xd4, 0xef}, {0xe6, 0xec}, {0xf7, 0xe1}, {0x01, 0xba},
{0x02, 0x9b}, {0xf9, 0x03}, {0x04, 0x05}, {0xf3, 0x06}, {0x07, 0x08},
{0xe9, 0xa0}, {0x09, 0x80}, {0xe5, 0x0a}, },
{ {0x15, 0x16}, {0xa7, 0xba}, {0xe3, 0xf7}, {0xf2, 0xad}, {0xe2, 0x01},
{0x02, 0x9b}, {0xe6, 0x03}, {0xed, 0xf6}, {0x04, 0xeb}, {0x05, 0xf4},
{0x06, 0x07}, {0x08, 0xf3}, {0x09, 0xf5}, {0x0a, 0xef}, {0x0b, 0x0c},
{0x80, 0xf9}, {0xe1, 0x0d}, {0xe4, 0xe9}, {0xa0, 0x0e}, {0x0f, 0xec},
{0xe5, 0x10}, {0x11, 0x12}, {0x13, 0x14}, },
{ {0x0a, 0x0b}, {0xf9, 0x9b}, {0xf5, 0xf3}, {0x01, 0x02}, {0xe2, 0xed},
{0x80, 0x03}, {0xf0, 0xef}, {0x04, 0xa0}, {0x05, 0xe9}, {0x06, 0xe1},
{0x07, 0x08}, {0x09, 0xe5}, },
{ {0x18, 0x19}, {0xe2, 0xea}, {0xf2, 0xe8}, {0xec, 0xed}, {0xfa, 0x9b},
{0x01, 0xf5}, {0x02, 0x03}, {0xf6, 0x04}, {0xba, 0xe6}, {0x05, 0x06},
{0xeb, 0xef}, {0x07, 0xa7}, {0xf9, 0x08}, {0x09, 0x0a}, {0x0b, 0xe3},
{0x0c, 0xee}, {0xe1, 0x0d}, {0xf3, 0x0e}, {0xe9, 0x0f}, {0x10, 0xf4},
{0x80, 0xe4}, {0xe5, 0x11}, {0x12, 0xe7}, {0xa0, 0x13}, {0x14, 0x15},
{0x16, 0x17}, },
{ {0x1b, 0x1c}, {0xae, 0xfa}, {0xbf, 0x01}, {0xa7, 0x9b}, {0x02, 0xe9},
{0xf8, 0xf9}, {0x03, 0xe5}, {0xe8, 0x04}, {0xe1, 0xeb}, {0x05, 0xe2},
{0x06, 0x07}, {0xe3, 0x08}, {0xe7, 0xf4}, {0x09, 0x80}, {0xf6, 0xf0},
{0x0a, 0xe4}, {0x0b, 0xf3}, {0xf7, 0x0c}, {0x0d, 0xef}, {0xec, 0xa0},
{0x0e, 0x0f}, {0xed, 0xe6}, {0x10, 0xf5}, {0x11, 0x12}, {0x13, 0x14},
{0x15, 0xf2}, {0x16, 0xee}, {0x17, 0x18}, {0x19, 0x1a}, },
{ {0x0e, 0x0f}, {0xed, 0xa7}, {0x9b, 0xe4}, {0x01, 0xf9}, {0xf3, 0xf2},
{0xf4, 0x02}, {0xe8, 0x03}, {0xec, 0xf0}, {0x04, 0xe1}, {0xe9, 0x05},
{0x06, 0x80}, {0xa0, 0x07}, {0x08, 0x09}, {0x0a, 0xe5}, {0xef, 0x0b},
{0x0c, 0x0d}, },
{ {0x9b, 0xf5}, },
{ {0x18, 0x19}, {0xba, 0xac}, {0xf6, 0x9b}, {0xf0, 0xe2}, {0x01, 0xe6},
{0x02, 0xa7}, {0xae, 0xe7}, {0x03, 0xe3}, {0xf5, 0x04}, {0xed, 0x05},
{0x06, 0x07}, {0xeb, 0x08}, {0x09, 0xee}, {0xf2, 0x0a}, {0xe4, 0x0b},
{0xf9, 0xec}, {0x0c, 0x0d}, {0xf4, 0x80}, {0x0e, 0xef}, {0xf3, 0xa0},
{0xe1, 0x0f}, {0xe9, 0x10}, {0x11, 0xe5}, {0x12, 0x13}, {0x14, 0x15},
{0x16, 0x17}, },
{ {0x19, 0x1a}, {0xa7, 0xac}, {0xbf, 0xc3}, {0xc8, 0xe4}, {0xe6, 0xed},
{0xf2, 0xae}, {0xec, 0xee}, {0xf9, 0x01}, {0x02, 0x03}, {0x04, 0xba},
{0x05, 0x9b}, {0xf5, 0x06}, {0x07, 0x08}, {0x09, 0xeb}, {0xf0, 0x0a},
{0x0b, 0x0c}, {0xe1, 0xe3}, {0x0d, 0xe8}, {0x0e, 0x0f}, {0xef, 0x10},
{0x11, 0xf3}, {0x12, 0xe9}, {0x13, 0xe5}, {0x14, 0x15}, {0xf4, 0x16},
{0x17, 0xa0}, {0x18, 0x80}, },
{ {0x14, 0x15}, {0xba, 0xbf}, {0xe4, 0xf7}, {0x9b, 0xa7}, {0x01, 0xee},
{0x02, 0x03}, {0x04, 0xe3}, {0xe2, 0xed}, {0x05, 0xf9}, {0x06, 0xf4},
{0x07, 0xec}, {0x08, 0xf5}, {0xf2, 0x09}, {0xe1, 0xf3}, {0x0a, 0xef},
{0x0b, 0x0c}, {0x0d, 0xe9}, {0x80, 0xe5}, {0x0e, 0xa0}, {0x0f, 0xe8},
{0x10, 0x11}, {0x12, 0x13}, },
{ {0x11, 0x12}, {0xeb, 0xfa}, {0x80, 0xe6}, {0x9b, 0x01}, {0xa0, 0x02},
{0x03, 0xe9}, {0xe1, 0x04}, {0xe4, 0xf0}, {0xed, 0xe2}, {0xe3, 0xe7},
{0xec, 0x05}, {0xe5, 0x06}, {0x07, 0x08}, {0x09, 0xf4}, {0x0a, 0x0b},
{0x0c, 0xf3}, {0xee, 0x0d}, {0x0e, 0xf2}, {0x0f, 0x10}, },
{ {0x04, 0xe5}, {0xf3, 0xef}, {0x9b, 0x01}, {0xe1, 0x02}, {0x03, 0xe9}, },
{ {0x0b, 0x0c}, {0xa7, 0xe2}, {0xec, 0xe3}, {0xf2, 0x01}, {0x9b, 0x02},
{0x03, 0x04}, {0xe9, 0xef}, {0xee, 0xe5}, {0xe1, 0x80}, {0x05, 0xa0},
{0x06, 0x07}, {0x08, 0x09}, {0xf3, 0x0a}, },
{ {0x05, 0x06}, {0x9b, 0xa0}, {0xe1, 0xe5}, {0xe9, 0x01}, {0x80, 0xf0},
{0x02, 0xf4}, {0x03, 0x04}, },
{ {0xa0, 0x13}, {0xe3, 0xad}, {0xe4, 0xe9}, {0xee, 0xef}, {0xf0, 0xf4},
{0xf6, 0xa1}, {0xe1, 0xed}, {0x01, 0xe2}, {0x02, 0x03}, {0x04, 0xa7},
{0x05, 0x06}, {0xf7, 0x07}, {0x9b, 0xec}, {0x08, 0xe5}, {0x09, 0x0a},
{0x0b, 0x0c}, {0x0d, 0x0e}, {0xf3, 0x0f}, {0x10, 0x11}, {0x80, 0x12}, },
{ {0x05, 0x06}, {0xe5, 0xfa}, {0xa0, 0xf9}, {0x9b, 0x01}, {0x80, 0xe9},
{0x02, 0xe1}, {0x03, 0x04}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
{ {0x9b, 0x9b}, },
};
static inline void huffbuff_init(struct huffbuff *hbuf, uint8_t *buf, uint32_t buf_len)
{
memset(hbuf, 0, sizeof(struct huffbuff));
hbuf->buf = buf;
hbuf->buf_len = buf_len;
}
static inline int huffbuff_bits(struct huffbuff *hbuf, uint8_t nbits)
{
uint8_t result = 0;
if (nbits > 8)
return -1;
while(nbits--) {
if (hbuf->cur_byte >= hbuf->buf_len) {
return -1;
}
result <<= 1;
if (hbuf->buf[hbuf->cur_byte] & (0x80 >> hbuf->cur_bit))
result |= 1;
if (++hbuf->cur_bit > 7) {
hbuf->cur_byte++;
hbuf->cur_bit = 0;
}
}
return result;
}
static inline int append_unicode_char(uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos,
uint32_t c)
{
uint8_t tmp[3];
int tmplen = 0;
// encode the unicode character first of all
if (c < 0x80) {
tmp[0] = c;
tmplen = 1;
} else if (c < 0x800) {
tmp[0] = 0xc0 | ((c >> 6) & 0x1f);
tmp[1] = 0x80 | (c & 0x3f);
tmplen = 2;
} else if (c < 0x10000) {
tmp[0] = 0xe0 | ((c >> 12) & 0x0f);
tmp[1] = 0x80 | ((c >> 6) & 0x3f);
tmp[2] = 0x80 | (c & 0x3f);
tmplen = 3;
} else {
return -1;
}
// do we have enough buffer space?
if ((*destbufpos + tmplen) >= *destbuflen) {
uint8_t *new_dest = realloc(*destbuf, *destbuflen + DEST_ALLOC_DELTA);
if (new_dest == NULL)
return -ENOMEM;
*destbuf = new_dest;
*destbuflen += DEST_ALLOC_DELTA;
}
// copy it into position
memcpy(*destbuf + *destbufpos, tmp, tmplen);
*destbufpos += tmplen;
return 0;
}
static inline int unicode_decode(uint8_t *srcbuf, size_t srcbuflen, int mode,
uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos)
{
size_t i;
uint32_t msb = mode << 8;
for(i=0; i< srcbuflen; i++) {
if (append_unicode_char(destbuf, destbuflen, destbufpos, msb + srcbuf[i]))
return -1;
}
return *destbufpos;
}
static int huffman_decode_uncompressed(struct huffbuff *hbuf,
uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos)
{
int c;
while(hbuf->cur_byte < hbuf->buf_len) {
// get next byte
if ((c = huffbuff_bits(hbuf, 8)) < 0)
return -1;
switch(c) {
case HUFFSTRING_END:
return 0;
case HUFFSTRING_ESCAPE:
return HUFFSTRING_ESCAPE;
default:
if (append_unicode_char(destbuf, destbuflen, destbufpos, c))
return -1;
// if it is 7 bit, we swap back to the compressed context
if ((c & 0x80) == 0)
return c;
// characters following an 8 bit uncompressed char are uncompressed as well
break;
}
}
// ran out of string; pretend we saw an end of string char
return HUFFSTRING_END;
}
static int huffman_decode(uint8_t *src, size_t srclen,
uint8_t **destbuf, size_t *destbuflen, size_t *destbufpos,
struct hufftree_entry hufftree[][128])
{
struct huffbuff hbuf;
int bit;
struct hufftree_entry *tree = hufftree[0];
uint8_t treeidx = 0;
uint8_t treeval;
int tmp;
huffbuff_init(&hbuf, src, srclen);
while(hbuf.cur_byte < hbuf.buf_len) {
// get the next bit
if ((bit = huffbuff_bits(&hbuf, 1)) < 0)
return *destbufpos;
if (!bit) {
treeval = tree[treeidx].left_idx;
} else {
treeval = tree[treeidx].right_idx;
}
if (treeval & HUFFTREE_LITERAL_MASK) {
switch(treeval & ~HUFFTREE_LITERAL_MASK) {
case HUFFSTRING_END:
return 0;
case HUFFSTRING_ESCAPE:
if ((tmp =
huffman_decode_uncompressed(&hbuf,
destbuf, destbuflen, destbufpos)) < 0)
return tmp;
if (tmp == 0)
return *destbufpos;
tree = hufftree[tmp];
treeidx = 0;
break;
default:
// stash it
if (append_unicode_char(destbuf, destbuflen, destbufpos,
treeval & ~HUFFTREE_LITERAL_MASK))
return -1;
tree = hufftree[treeval & ~HUFFTREE_LITERAL_MASK];
treeidx = 0;
break;
}
} else {
treeidx = treeval;
}
}
return *destbufpos;
}
int atsc_text_segment_decode(struct atsc_text_string_segment *segment,
uint8_t **destbuf, size_t *destbufsize, size_t *destbufpos)
{
if (segment->mode > ATSC_TEXT_SEGMENT_MODE_UNICODE_RANGE_MAX)
return -1;
// mode==0 MUST be used for compressed text
if ((segment->mode) && (segment->compression_type))
return -1;
uint8_t *buf = atsc_text_string_segment_bytes(segment);
switch(segment->compression_type) {
case ATSC_TEXT_COMPRESS_NONE:
return unicode_decode(buf, segment->number_bytes, segment->mode,
destbuf, destbufsize, destbufpos);
case ATSC_TEXT_COMPRESS_PROGRAM_TITLE:
return huffman_decode(buf, segment->number_bytes,
destbuf, destbufsize, destbufpos,
program_title_hufftree);
case ATSC_TEXT_COMPRESS_PROGRAM_DESCRIPTION:
return huffman_decode(buf, segment->number_bytes,
destbuf, destbufsize, destbufpos,
program_description_hufftree);
}
return -1;
}

@ -0,0 +1,137 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_CAPTION_SERVICE_DESCRIPTOR
#define _UCSI_ATSC_CAPTION_SERVICE_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
/**
* atsc_caption_service_descriptor structure.
*/
struct atsc_caption_service_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 3; ,
uint8_t number_of_services : 5; );
/* struct atsc_caption_service_entry entries[] */
} __ucsi_packed;
/**
* An entry in the entries field of a atsc_caption_service_descriptor.
*/
struct atsc_caption_service_entry {
iso639lang_t language_code;
EBIT3(uint8_t digital_cc : 1; ,
uint8_t reserved : 1; ,
uint8_t value : 6; );
EBIT3(uint16_t easy_reader : 1; ,
uint16_t wide_aspect_ratio : 1; ,
uint16_t reserved1 :14; );
} __ucsi_packed;
/**
* Process an atsc_caption_service_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_caption_service_descriptor pointer, or NULL on error.
*/
static inline struct atsc_caption_service_descriptor*
atsc_caption_service_descriptor_codec(struct descriptor* d)
{
struct atsc_caption_service_descriptor *ret =
(struct atsc_caption_service_descriptor *) d;
uint8_t *buf = (uint8_t*) d + 2;
int pos = 0;
int idx;
if (d->len < 1)
return NULL;
pos++;
for(idx = 0; idx < ret->number_of_services; idx++) {
if (d->len < (pos + sizeof(struct atsc_caption_service_entry)))
return NULL;
bswap16(buf+pos+4);
pos += sizeof(struct atsc_caption_service_entry);
}
return (struct atsc_caption_service_descriptor*) d;
}
/**
* Iterator for entries field of a atsc_caption_service_descriptor.
*
* @param d atsc_caption_service_descriptor pointer.
* @param pos Variable holding a pointer to the current atsc_caption_service_entry.
* @param idx Field iterator integer.
*/
#define atsc_caption_service_descriptor_entries_for_each(d, pos, idx) \
for ((pos) = atsc_caption_service_descriptor_entries_first(d), idx=0; \
(pos); \
(pos) = atsc_caption_service_descriptor_entries_next(d, pos, ++idx))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_caption_service_entry*
atsc_caption_service_descriptor_entries_first(struct atsc_caption_service_descriptor *d)
{
if (d->number_of_services == 0)
return NULL;
return (struct atsc_caption_service_entry *)
((uint8_t*) d + sizeof(struct atsc_caption_service_descriptor));
}
static inline struct atsc_caption_service_entry*
atsc_caption_service_descriptor_entries_next(struct atsc_caption_service_descriptor *d,
struct atsc_caption_service_entry *pos,
int idx)
{
if (idx >= d->number_of_services)
return NULL;
return (struct atsc_caption_service_entry *)
((uint8_t *) pos + sizeof(struct atsc_caption_service_entry));
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,92 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_COMPONENT_NAME_DESCRIPTOR
#define _UCSI_ATSC_COMPONENT_NAME_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
#include <libucsi/atsc/types.h>
/**
* atsc_component_name_descriptor structure.
*/
struct atsc_component_name_descriptor {
struct descriptor d;
/* struct atsc_text text[] */
} __ucsi_packed;
/**
* Process an atsc_component_name_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_component_name_descriptor pointer, or NULL on error.
*/
static inline struct atsc_component_name_descriptor*
atsc_component_name_descriptor_codec(struct descriptor* d)
{
uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_component_name_descriptor);
if (atsc_text_validate(txt, d->len))
return NULL;
return (struct atsc_component_name_descriptor*) d;
}
/**
* Accessor for the text field of an atsc_component_name_descriptor.
*
* @param d atsc_component_name_descriptor pointer.
* @return Pointer to the atsc_text data, or NULL on error.
*/
static inline struct atsc_text*
atsc_component_name_descriptor_text(struct atsc_component_name_descriptor *d)
{
uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_component_name_descriptor);
return (struct atsc_text*) txt;
}
/**
* Accessor for the length of the text field of an atsc_component_name_descriptor_text.
*
* @param d atsc_component_name_descriptor pointer.
* @return The length in bytes.
*/
static inline int
atsc_component_name_descriptor_text_length(struct atsc_component_name_descriptor *d)
{
return d->d.len;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,235 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_CONTENT_ADVISORY_DESCRIPTOR
#define _UCSI_ATSC_CONTENT_ADVISORY_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
/**
* atsc_content_advisory_descriptor structure.
*/
struct atsc_content_advisory_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 2; ,
uint8_t rating_region_count : 6; );
/* struct atsc_content_advisory_entry entries[] */
} __ucsi_packed;
/**
* An entry in the entries field of a atsc_content_advisory_descriptor.
*/
struct atsc_content_advisory_entry {
uint8_t rating_region;
uint8_t rated_dimensions;
/* struct atsc_content_advisory_entry_dimension dimensions[] */
/* struct atsc_content_advisory_entry_part2 part2 */
} __ucsi_packed;
/**
* An entry in the entries field of a atsc_content_advisory_descriptor.
*/
struct atsc_content_advisory_entry_dimension {
uint8_t rating_dimension_j;
EBIT2(uint8_t reserved : 4; ,
uint8_t rating_value : 4; );
} __ucsi_packed;
/**
* Part2 of an atsc_content_advisory_entry.
*/
struct atsc_content_advisory_entry_part2 {
uint8_t rating_description_length;
/* struct atsc_text description */
} __ucsi_packed;
/**
* Process an atsc_content_advisory_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_content_advisory_descriptor pointer, or NULL on error.
*/
static inline struct atsc_content_advisory_descriptor*
atsc_content_advisory_descriptor_codec(struct descriptor* d)
{
struct atsc_content_advisory_descriptor *ret =
(struct atsc_content_advisory_descriptor *) d;
uint8_t *buf = (uint8_t*) d + 2;
int pos = 0;
int idx;
if (d->len < 1)
return NULL;
pos++;
for(idx = 0; idx < ret->rating_region_count; idx++) {
if (d->len < (pos + sizeof(struct atsc_content_advisory_entry)))
return NULL;
struct atsc_content_advisory_entry *entry =
(struct atsc_content_advisory_entry *) (buf + pos);
pos += sizeof(struct atsc_content_advisory_entry);
if (d->len < (pos + (sizeof(struct atsc_content_advisory_entry_dimension) *
entry->rated_dimensions)))
return NULL;
pos += sizeof(struct atsc_content_advisory_entry_dimension) * entry->rated_dimensions;
if (d->len < (pos + sizeof(struct atsc_content_advisory_entry_part2)))
return NULL;
struct atsc_content_advisory_entry_part2 *part2 =
(struct atsc_content_advisory_entry_part2 *) (buf + pos);
pos += sizeof(struct atsc_content_advisory_entry_part2);
if (d->len < (pos + part2->rating_description_length))
return NULL;
if (atsc_text_validate(buf+pos, part2->rating_description_length))
return NULL;
pos += part2->rating_description_length;
}
return (struct atsc_content_advisory_descriptor*) d;
}
/**
* Iterator for entries field of a atsc_content_advisory_descriptor.
*
* @param d atsc_content_advisory_descriptor pointer.
* @param pos Variable holding a pointer to the current atsc_content_advisory_entry.
* @param idx Integer used to count which entry we are in.
*/
#define atsc_content_advisory_descriptor_entries_for_each(d, pos, idx) \
for ((pos) = atsc_content_advisory_descriptor_entries_first(d), idx=0; \
(pos); \
(pos) = atsc_content_advisory_descriptor_entries_next(d, pos, ++idx))
/**
* Iterator for dimensions field of a atsc_content_advisory_entry.
*
* @param d atsc_content_advisory_entry pointer.
* @param pos Variable holding a pointer to the current atsc_content_advisory_entry_dimension.
* @param idx Integer used to count which dimension we are in.
*/
#define atsc_content_advisory_entry_dimensions_for_each(d, pos, idx) \
for ((pos) = atsc_content_advisory_entry_dimensions_first(d), idx=0; \
(pos); \
(pos) = atsc_content_advisory_entry_dimensions_next(d, pos, ++idx))
/**
* Accessor for the part2 field of an atsc_content_advisory_entry.
*
* @param entry atsc_content_advisory_entry pointer.
* @return struct atsc_content_advisory_entry_part2 pointer.
*/
static inline struct atsc_content_advisory_entry_part2 *
atsc_content_advisory_entry_part2(struct atsc_content_advisory_entry *entry)
{
int pos = sizeof(struct atsc_content_advisory_entry);
pos += entry->rated_dimensions * sizeof(struct atsc_content_advisory_entry_dimension);
return (struct atsc_content_advisory_entry_part2 *) (((uint8_t*) entry) + pos);
}
/**
* Accessor for the description field of an atsc_content_advisory_entry_part2.
*
* @param part2 atsc_content_advisory_entry_part2 pointer.
* @return Pointer to the atsc_text data, or NULL on error.
*/
static inline struct atsc_text*
atsc_content_advisory_entry_part2_description(struct atsc_content_advisory_entry_part2 *part2)
{
uint8_t *txt = ((uint8_t*) part2) + sizeof(struct atsc_content_advisory_entry_part2);
return (struct atsc_text *) txt;
}
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_content_advisory_entry*
atsc_content_advisory_descriptor_entries_first(struct atsc_content_advisory_descriptor *d)
{
if (d->rating_region_count == 0)
return NULL;
return (struct atsc_content_advisory_entry *)
((uint8_t*) d + sizeof(struct atsc_content_advisory_descriptor));
}
static inline struct atsc_content_advisory_entry*
atsc_content_advisory_descriptor_entries_next(struct atsc_content_advisory_descriptor *d,
struct atsc_content_advisory_entry *pos,
int idx)
{
if (idx >= d->rating_region_count)
return NULL;
struct atsc_content_advisory_entry_part2 *part2 =
atsc_content_advisory_entry_part2(pos);
return (struct atsc_content_advisory_entry *)
((uint8_t *) part2 +
sizeof(struct atsc_content_advisory_entry_part2) +
part2->rating_description_length);
}
static inline struct atsc_content_advisory_entry_dimension*
atsc_content_advisory_entry_dimensions_first(struct atsc_content_advisory_entry *e)
{
if (e->rated_dimensions == 0)
return NULL;
return (struct atsc_content_advisory_entry_dimension *)
((uint8_t*) e + sizeof(struct atsc_content_advisory_entry));
}
static inline struct atsc_content_advisory_entry_dimension*
atsc_content_advisory_entry_dimensions_next(struct atsc_content_advisory_entry *e,
struct atsc_content_advisory_entry_dimension *pos,
int idx)
{
uint8_t *next = (uint8_t *) pos + sizeof(struct atsc_content_advisory_entry_dimension);
if (idx >= e->rated_dimensions)
return NULL;
return (struct atsc_content_advisory_entry_dimension *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,77 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/cvct_section.h>
struct atsc_cvct_section *atsc_cvct_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = sizeof(struct atsc_section_psip);
size_t len = section_ext_length(&(psip->ext_head));
int idx;
if (len < sizeof(struct atsc_cvct_section))
return NULL;
struct atsc_cvct_section *cvct = (struct atsc_cvct_section *) psip;
pos++;
for(idx =0; idx < cvct->num_channels_in_section; idx++) {
if ((pos + sizeof(struct atsc_cvct_channel)) > len)
return NULL;
struct atsc_cvct_channel *channel = (struct atsc_cvct_channel *) (buf+pos);
pos += 7*2;
bswap32(buf+pos);
bswap32(buf+pos+4);
bswap16(buf+pos+8);
bswap16(buf+pos+10);
bswap16(buf+pos+12);
bswap16(buf+pos+14);
bswap16(buf+pos+16);
pos+=18;
if ((pos + channel->descriptors_length) > len)
return NULL;
if (verify_descriptors(buf + pos, channel->descriptors_length))
return NULL;
pos += channel->descriptors_length;
}
if ((pos + sizeof(struct atsc_cvct_section_part2)) > len)
return NULL;
struct atsc_cvct_section_part2 *part2 = (struct atsc_cvct_section_part2 *) (buf+pos);
bswap16(buf+pos);
pos+=2;
if ((pos + part2->descriptors_length) > len)
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
if (pos != len)
return NULL;
return (struct atsc_cvct_section *) psip;
}

@ -0,0 +1,228 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_CVCT_SECTION_H
#define _UCSI_ATSC_CVCT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
/**
* atsc_cvct_section structure.
*/
struct atsc_cvct_section {
struct atsc_section_psip head;
uint8_t num_channels_in_section;
/* struct atsc_cvct_channel channels[] */
/* struct atsc_cvct_channel_part2 part2 */
} __ucsi_packed;
struct atsc_cvct_channel {
uint16_t short_name[7]; // UTF-16 network ordered
EBIT4(uint32_t reserved : 4; ,
uint32_t major_channel_number :10; ,
uint32_t minor_channel_number :10; ,
uint32_t modulation_mode : 8; );
uint32_t carrier_frequency;
uint16_t channel_TSID;
uint16_t program_number;
EBIT8(uint16_t ETM_location : 2; ,
uint16_t access_controlled : 1; ,
uint16_t hidden : 1; ,
uint16_t path_select : 1; ,
uint16_t out_of_band : 1; ,
uint16_t hide_guide : 1; ,
uint16_t reserved2 : 3; ,
uint16_t service_type : 6; );
uint16_t source_id;
EBIT2(uint16_t reserved3 : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
struct atsc_cvct_section_part2 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
static inline struct atsc_cvct_channel *atsc_cvct_section_channels_first(struct atsc_cvct_section *cvct);
static inline struct atsc_cvct_channel *
atsc_cvct_section_channels_next(struct atsc_cvct_section *cvct, struct atsc_cvct_channel *pos, int idx);
/**
* Process a atsc_cvct_section.
*
* @param section Pointer to anj atsc_section_psip structure.
* @return atsc_cvct_section pointer, or NULL on error.
*/
struct atsc_cvct_section *atsc_cvct_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the transport_stream_id field of a CVCT.
*
* @param cvdt CVDT pointer.
* @return The transport_stream_id.
*/
static inline uint16_t atsc_cvct_section_transport_stream_id(struct atsc_cvct_section *cvct)
{
return cvct->head.ext_head.table_id_ext;
}
/**
* Iterator for the tables field in an atsc_cvct_section.
*
* @param mgt atsc_cvct_section pointer.
* @param pos Variable containing a pointer to the current atsc_cvct_channel.
* @param idx Integer used to count which table we in.
*/
#define atsc_cvct_section_channels_for_each(mgt, pos, idx) \
for ((pos) = atsc_cvct_section_channels_first(mgt), idx=0; \
(pos); \
(pos) = atsc_cvct_section_channels_next(mgt, pos, ++idx))
/**
* Iterator for the descriptors field in a atsc_cvct_channel structure.
*
* @param table atsc_cvct_channel pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_cvct_channel_descriptors_for_each(table, pos) \
for ((pos) = atsc_cvct_channel_descriptors_first(table); \
(pos); \
(pos) = atsc_cvct_channel_descriptors_next(table, pos))
/**
* Accessor for the second part of an atsc_cvct_section.
*
* @param mgt atsc_cvct_section pointer.
* @return atsc_cvct_section_part2 pointer.
*/
static inline struct atsc_cvct_section_part2 *
atsc_cvct_section_part2(struct atsc_cvct_section *mgt)
{
int pos = sizeof(struct atsc_cvct_section);
struct atsc_cvct_channel *cur_table;
int idx;
atsc_cvct_section_channels_for_each(mgt, cur_table, idx) {
pos += sizeof(struct atsc_cvct_channel);
pos += cur_table->descriptors_length;
}
return (struct atsc_cvct_section_part2 *) (((uint8_t*) mgt) + pos);
}
/**
* Iterator for the descriptors field in a atsc_cvct_section structure.
*
* @param part2 atsc_cvct_section_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_cvct_section_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_cvct_section_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_cvct_section_part2_descriptors_next(part2, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_cvct_channel *
atsc_cvct_section_channels_first(struct atsc_cvct_section *cvct)
{
size_t pos = sizeof(struct atsc_cvct_section);
if (cvct->num_channels_in_section == 0)
return NULL;
return (struct atsc_cvct_channel*) (((uint8_t *) cvct) + pos);
}
static inline struct atsc_cvct_channel *
atsc_cvct_section_channels_next(struct atsc_cvct_section *cvct,
struct atsc_cvct_channel *pos,
int idx)
{
if (idx >= cvct->num_channels_in_section)
return NULL;
return (struct atsc_cvct_channel *)
(((uint8_t*) pos) + sizeof(struct atsc_cvct_channel) + pos->descriptors_length);
}
static inline struct descriptor *
atsc_cvct_channel_descriptors_first(struct atsc_cvct_channel *table)
{
size_t pos = sizeof(struct atsc_cvct_channel);
if (table->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) table) + pos);
}
static inline struct descriptor *
atsc_cvct_channel_descriptors_next(struct atsc_cvct_channel *table,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) table + sizeof(struct atsc_cvct_channel),
table->descriptors_length,
pos);
}
static inline struct descriptor *
atsc_cvct_section_part2_descriptors_first(struct atsc_cvct_section_part2 *part2)
{
size_t pos = sizeof(struct atsc_cvct_section_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_cvct_section_part2_descriptors_next(struct atsc_cvct_section_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_cvct_section_part2),
part2->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,107 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_DCC_ARRIVING_REQUEST_DESCRIPTOR
#define _UCSI_ATSC_DCC_ARRIVING_REQUEST_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
enum atsc_dcc_arriving_request_type {
DCC_ARRIVAL_TYPE_DEFER_10SEC = 0x01,
DCC_ARRIVAL_TYPE_DEFER = 0x02,
};
/**
* atsc_dcc_arriving_request_descriptor structure.
*/
struct atsc_dcc_arriving_request_descriptor {
struct descriptor d;
uint8_t dcc_arriving_request_type;
uint8_t dcc_arriving_request_text_length;
/* struct atsc_text text[] */
} __ucsi_packed;
/**
* Process an atsc_dcc_arriving_request_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_dcc_arriving_request_descriptor pointer, or NULL on error.
*/
static inline struct atsc_dcc_arriving_request_descriptor*
atsc_dcc_arriving_request_descriptor_codec(struct descriptor* d)
{
struct atsc_dcc_arriving_request_descriptor *ret =
(struct atsc_dcc_arriving_request_descriptor *) d;
if (d->len < 2)
return NULL;
if (d->len != 2 + ret->dcc_arriving_request_text_length)
return NULL;
if (atsc_text_validate((uint8_t*) d + sizeof(struct atsc_dcc_arriving_request_descriptor),
ret->dcc_arriving_request_text_length))
return NULL;
return (struct atsc_dcc_arriving_request_descriptor*) d;
}
/**
* Accessor for the text field of an atsc_dcc_arriving_request_descriptor.
*
* @param d atsc_dcc_arriving_request_descriptor pointer.
* @return Pointer to the atsc_text data, or NULL on error.
*/
static inline struct atsc_text*
atsc_dcc_arriving_request_descriptor_text(struct atsc_dcc_arriving_request_descriptor *d)
{
uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_dcc_arriving_request_descriptor);
return (struct atsc_text*) txt;
}
/**
* Accessor for the length of the text field of an atsc_dcc_arriving_request_descriptor.
*
* @param d atsc_dcc_arriving_request_descriptor pointer.
* @return The length in bytes.
*/
static inline int
atsc_dcc_arriving_request_descriptor_text_length(struct
atsc_dcc_arriving_request_descriptor *d)
{
return d->d.len - 2;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,108 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_DCC_DEPARTING_REQUEST_DESCRIPTOR
#define _UCSI_ATSC_DCC_DEPARTING_REQUEST_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
enum atsc_dcc_departing_request_type {
DCC_DEPART_TYPE_IMMEDIATE = 0x01,
DCC_DEPART_TYPE_DEFER_10SEC = 0x02,
DCC_DEPART_TYPE_DEFER = 0x03,
};
/**
* atsc_dcc_departing_request_descriptor structure.
*/
struct atsc_dcc_departing_request_descriptor {
struct descriptor d;
uint8_t dcc_departing_request_type;
uint8_t dcc_departing_request_text_length;
/* struct atsc_text text[] */
} __ucsi_packed;
/**
* Process an atsc_dcc_departing_request_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_dcc_departing_request_descriptor pointer, or NULL on error.
*/
static inline struct atsc_dcc_departing_request_descriptor*
atsc_dcc_departing_request_descriptor_codec(struct descriptor* d)
{
struct atsc_dcc_departing_request_descriptor *ret =
(struct atsc_dcc_departing_request_descriptor *) d;
if (d->len < 2)
return NULL;
if (d->len != 2 + ret->dcc_departing_request_text_length)
return NULL;
if (atsc_text_validate(((uint8_t*) d) + sizeof(struct atsc_dcc_departing_request_descriptor),
ret->dcc_departing_request_text_length))
return NULL;
return (struct atsc_dcc_departing_request_descriptor*) d;
}
/**
* Accessor for the text field of an atsc_dcc_departing_request_descriptor.
*
* @param d atsc_dcc_departing_request_descriptor pointer.
* @return Pointer to the atsc_text data, or NULL on error.
*/
static inline struct atsc_text*
atsc_dcc_departing_request_descriptor_text(struct atsc_dcc_departing_request_descriptor *d)
{
uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_dcc_departing_request_descriptor);
return (struct atsc_text*) txt;
}
/**
* Accessor for the length of the text field of an atsc_dcc_departing_request_descriptor.
*
* @param d atsc_dcc_departing_request_descriptor pointer.
* @return The length in bytes.
*/
static inline int
atsc_dcc_departing_request_descriptor_text_length(struct
atsc_dcc_departing_request_descriptor *d)
{
return d->d.len - 2;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,109 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/dccsct_section.h>
struct atsc_dccsct_section *atsc_dccsct_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = 0;
size_t len = section_ext_length(&(psip->ext_head));
int idx;
if (len < sizeof(struct atsc_dccsct_section))
return NULL;
struct atsc_dccsct_section *dccsct = (struct atsc_dccsct_section *) psip;
pos += sizeof(struct atsc_dccsct_section);
for(idx =0; idx < dccsct->updates_defined; idx++) {
if (len < (pos + sizeof(struct atsc_dccsct_update)))
return NULL;
struct atsc_dccsct_update *update = (struct atsc_dccsct_update *) (buf+pos);
pos += sizeof(struct atsc_dccsct_update);
if (len < (pos + update->update_data_length))
return NULL;
switch(update->update_type) {
case ATSC_DCCST_UPDATE_NEW_GENRE: {
int sublen = sizeof(struct atsc_dccsct_update_new_genre);
if (update->update_data_length < sublen)
return NULL;
if (atsc_text_validate(buf+pos+sublen, update->update_data_length - sublen))
return NULL;
break;
}
case ATSC_DCCST_UPDATE_NEW_STATE: {
int sublen = sizeof(struct atsc_dccsct_update_new_state);
if (update->update_data_length < sublen)
return NULL;
if (atsc_text_validate(buf+pos+sublen, update->update_data_length - sublen))
return NULL;
break;
}
case ATSC_DCCST_UPDATE_NEW_COUNTY: {
int sublen = sizeof(struct atsc_dccsct_update_new_county);
if (update->update_data_length < sublen)
return NULL;
bswap16(buf+pos+1);
if (atsc_text_validate(buf+pos+sublen, update->update_data_length - sublen))
return NULL;
break;
}
}
pos += update->update_data_length;
if (len < (pos + sizeof(struct atsc_dccsct_update_part2)))
return NULL;
struct atsc_dccsct_update_part2 *part2 = (struct atsc_dccsct_update_part2 *) buf + pos;
bswap16(buf+pos);
pos += sizeof(struct atsc_dccsct_update_part2);
if (len < (pos + part2->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
}
if (len < (pos + sizeof(struct atsc_dccsct_section_part2)))
return NULL;
struct atsc_dccsct_section_part2 *part2 = (struct atsc_dccsct_section_part2 *) (buf+pos);
bswap16(buf+pos);
pos += sizeof(struct atsc_dccsct_section_part2);
if (len < (pos + part2->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
if (pos != len)
return NULL;
return (struct atsc_dccsct_section *) psip;
}

@ -0,0 +1,327 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_DCCSCT_SECTION_H
#define _UCSI_ATSC_DCCSCT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
#include <libucsi/atsc/types.h>
enum atsc_dccst_update_types {
ATSC_DCCST_UPDATE_NEW_GENRE = 0x01,
ATSC_DCCST_UPDATE_NEW_STATE = 0x02,
ATSC_DCCST_UPDATE_NEW_COUNTY = 0x03,
};
/**
* atsc_dccsct_section structure.
*/
struct atsc_dccsct_section {
struct atsc_section_psip head;
uint8_t updates_defined;
/* struct atsc_dccsct_update updates */
/* struct atsc_dccsct_section_part2 part2 */
} __ucsi_packed;
struct atsc_dccsct_update {
uint8_t update_type;
uint8_t update_data_length;
/* struct atsc_dccsct_update_XXX data -- depends on update_type */
/* struct atsc_dccsct_update_part2 part2 */
} __ucsi_packed;
struct atsc_dccsct_update_new_genre {
uint8_t genre_category_code;
/* atsc_text name */
} __ucsi_packed;
struct atsc_dccsct_update_new_state {
uint8_t dcc_state_location_code;
/* atsc_text name */
} __ucsi_packed;
struct atsc_dccsct_update_new_county {
uint8_t state_code;
EBIT2(uint16_t reserved : 6; ,
uint16_t dcc_county_location_code :10; );
/* atsc_text name */
} __ucsi_packed;
struct atsc_dccsct_update_part2 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
struct atsc_dccsct_section_part2 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
/**
* Process an atsc_dccsct_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_dccsct_section pointer, or NULL on error.
*/
struct atsc_dccsct_section *atsc_dccsct_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the dccsct_type field of a dccsct.
*
* @param dccsct dccsct pointer.
* @return The dccsct_type.
*/
static inline uint16_t atsc_dccsct_section_dccsct_type(struct atsc_dccsct_section *dccsct)
{
return dccsct->head.ext_head.table_id_ext;
}
/**
* Iterator for the updates field in an atsc_dccsct_section.
*
* @param dccsct atsc_dccsct_section pointer.
* @param pos Variable containing a pointer to the current atsc_dccsct_update.
* @param idx Integer used to count which test we are in.
*/
#define atsc_dccsct_section_updates_for_each(dccsct, pos, idx) \
for ((pos) = atsc_dccsct_section_updates_first(dccsct), idx=0; \
(pos); \
(pos) = atsc_dccsct_section_updates_next(dccsct, pos, ++idx))
/**
* Accessor for the data field of a new genre atsc_dccsct_update.
*
* @param update atsc_dccsct_update pointer.
* @return struct atsc_dccsct_update_new_genre pointer.
*/
static inline struct atsc_dccsct_update_new_genre *atsc_dccsct_update_new_genre(struct atsc_dccsct_update *update)
{
if (update->update_type != ATSC_DCCST_UPDATE_NEW_GENRE)
return NULL;
return (struct atsc_dccsct_update_new_genre *)
(((uint8_t*) update) + sizeof(struct atsc_dccsct_update));
}
/**
* Accessor for the name field of an atsc_dccsct_update_new_genre.
*
* @param update atsc_dccsct_update_new_genre pointer.
* @return text pointer.
*/
static inline struct atsc_text *atsc_dccsct_update_new_genre_name(struct atsc_dccsct_update *update)
{
if ((update->update_data_length - 1) == 0)
return NULL;
return (struct atsc_text *)
(((uint8_t*) update) + sizeof(struct atsc_dccsct_update_new_genre));
}
/**
* Accessor for the data field of a new state atsc_dccsct_update.
*
* @param update atsc_dccsct_update pointer.
* @return struct atsc_dccsct_update_new_state pointer.
*/
static inline struct atsc_dccsct_update_new_state *
atsc_dccsct_update_new_state(struct atsc_dccsct_update *update)
{
if (update->update_type != ATSC_DCCST_UPDATE_NEW_STATE)
return NULL;
return (struct atsc_dccsct_update_new_state *)
(((uint8_t*) update) + sizeof(struct atsc_dccsct_update));
}
/**
* Accessor for the name field of an atsc_dccsct_update_new_state.
*
* @param update atsc_dccsct_update_new_state pointer.
* @return text pointer.
*/
static inline struct atsc_text *atsc_dccsct_update_new_state_name(struct atsc_dccsct_update *update)
{
if ((update->update_data_length - 1) == 0)
return NULL;
return (struct atsc_text *)
(((uint8_t*) update) + sizeof(struct atsc_dccsct_update_new_state));
}
/**
* Accessor for the data field of a new county atsc_dccsct_update.
*
* @param update atsc_dccsct_update pointer.
* @return struct atsc_dccsct_update_new_county pointer.
*/
static inline struct atsc_dccsct_update_new_county *
atsc_dccsct_update_new_county(struct atsc_dccsct_update *update)
{
if (update->update_type != ATSC_DCCST_UPDATE_NEW_COUNTY)
return NULL;
return (struct atsc_dccsct_update_new_county *)
(((uint8_t*) update) + sizeof(struct atsc_dccsct_update));
}
/**
* Accessor for the name field of an atsc_dccsct_update_new_county.
*
* @param update atsc_dccsct_update_new_county pointer.
* @return text pointer.
*/
static inline struct atsc_text *atsc_dccsct_update_new_county_name(struct atsc_dccsct_update *update)
{
if ((update->update_data_length - 3) == 0)
return NULL;
return (struct atsc_text*)
(((uint8_t*) update) + sizeof(struct atsc_dccsct_update_new_county));
}
/**
* Accessor for the part2 field of an atsc_dccsct_update.
*
* @param update atsc_dccsct_update pointer.
* @return struct atsc_dccsct_test_part2 pointer.
*/
static inline struct atsc_dccsct_update_part2 *atsc_dccsct_update_part2(struct atsc_dccsct_update *update)
{
int pos = sizeof(struct atsc_dccsct_update);
pos += update->update_data_length;
return (struct atsc_dccsct_update_part2 *) (((uint8_t*) update) + pos);
}
/**
* Iterator for the descriptors field in an atsc_dccsct_update_part2 structure.
*
* @param part2 atsc_dccsct_update_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_dccsct_update_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_dccsct_update_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_dccsct_update_part2_descriptors_next(part2, pos))
/**
* Iterator for the descriptors field in a atsc_dccsct_section_part2 structure.
*
* @param part2 atsc_dccsct_section_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_dccsct_section_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_dccsct_section_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_dccsct_section_part2_descriptors_next(part2, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_dccsct_update *
atsc_dccsct_section_updates_first(struct atsc_dccsct_section *dccsct)
{
size_t pos = sizeof(struct atsc_dccsct_section);
if (dccsct->updates_defined == 0)
return NULL;
return (struct atsc_dccsct_update*) (((uint8_t *) dccsct) + pos);
}
static inline struct atsc_dccsct_update*
atsc_dccsct_section_updates_next(struct atsc_dccsct_section *dccsct,
struct atsc_dccsct_update *pos,
int idx)
{
if (idx >= dccsct->updates_defined)
return NULL;
struct atsc_dccsct_update_part2 *part2 = atsc_dccsct_update_part2(pos);
int len = sizeof(struct atsc_dccsct_update_part2);
len += part2->descriptors_length;
return (struct atsc_dccsct_update *) (((uint8_t*) part2) + len);
}
static inline struct descriptor *
atsc_dccsct_update_part2_descriptors_first(struct atsc_dccsct_update_part2 *part2)
{
size_t pos = sizeof(struct atsc_dccsct_update_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_dccsct_update_part2_descriptors_next(struct atsc_dccsct_update_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dccsct_update_part2),
part2->descriptors_length,
pos);
}
static inline struct descriptor *
atsc_dccsct_section_part2_descriptors_first(struct atsc_dccsct_section_part2 *part2)
{
size_t pos = sizeof(struct atsc_dccsct_section_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_dccsct_section_part2_descriptors_next(struct atsc_dccsct_section_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dccsct_section_part2),
part2->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,96 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/dcct_section.h>
struct atsc_dcct_section *atsc_dcct_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = 0;
size_t len = section_ext_length(&(psip->ext_head));
int testidx;
int termidx;
if (len < sizeof(struct atsc_dcct_section))
return NULL;
struct atsc_dcct_section *dcct = (struct atsc_dcct_section *) psip;
pos += sizeof(struct atsc_dcct_section);
for(testidx =0; testidx < dcct->dcc_test_count; testidx++) {
if (len < (pos + sizeof(struct atsc_dcct_test)))
return NULL;
struct atsc_dcct_test *test = (struct atsc_dcct_test *) (buf+pos);
bswap24(buf+pos);
bswap24(buf+pos+3);
bswap32(buf+pos+6);
bswap32(buf+pos+10);
pos += sizeof(struct atsc_dcct_test);
for(termidx =0; termidx < test->dcc_term_count; termidx++) {
if (len < (pos + sizeof(struct atsc_dcct_term)))
return NULL;
struct atsc_dcct_term *term = (struct atsc_dcct_term *) (buf+pos);
bswap64(buf+pos+1);
bswap16(buf+pos+9);
pos += sizeof(struct atsc_dcct_term);
if (len < (pos + term->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, term->descriptors_length))
return NULL;
pos += term->descriptors_length;
}
if (len < (pos + sizeof(struct atsc_dcct_test_part2)))
return NULL;
struct atsc_dcct_test_part2 *part2 = (struct atsc_dcct_test_part2 *) (buf+pos);
bswap16(buf+pos);
pos += sizeof(struct atsc_dcct_test_part2);
if (len < (pos + part2->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
}
if (len < (pos + sizeof(struct atsc_dcct_section_part2)))
return NULL;
struct atsc_dcct_section_part2 *part2 = (struct atsc_dcct_section_part2 *) (buf+pos);
bswap16(buf+pos);
pos += sizeof(struct atsc_dcct_section_part2);
if (len < (pos + part2->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
if (pos != len)
return NULL;
return (struct atsc_dcct_section *) psip;
}

@ -0,0 +1,380 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_DCCT_SECTION_H
#define _UCSI_ATSC_DCCT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
#include <libucsi/atsc/types.h>
enum atsc_dcc_context {
ATSC_DCC_CONTEXT_TEMPORARY_RETUNE = 0,
ATSC_DCC_CONTEXT_CHANNEL_REDIRECT = 1,
};
enum atsc_dcc_selection_type {
ATSC_DCC_SELECTION_UNCONDITIONAL_CHANNEL_CHANGE = 0x00,
ATSC_DCC_SELECTION_NUMERIC_POSTAL_CODE_INCLUSION = 0x01,
ATSC_DCC_SELECTION_ALPHANUMERIC_POSTAL_CODE_INCLUSION = 0x02,
ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_ONE_OR_MORE = 0x05,
ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_ALL = 0x06,
ATSC_DCC_SELECTION_GENRE_CATEGORY_ONE_OR_MORE = 0x07,
ATSC_DCC_SELECTION_GENRE_CATEGORY_ALL = 0x08,
ATSC_DCC_SELECTION_CANNOT_BE_AUTHORIZED = 0x09,
ATSC_DCC_SELECTION_GEOGRAPHIC_LOCATION_INCLUSION = 0x0c,
ATSC_DCC_SELECTION_RATING_BLOCKED = 0x0d,
ATSC_DCC_SELECTION_RETURN_TO_ORIGINAL_CHANNEL = 0x0f,
ATSC_DCC_SELECTION_NUMERIC_POSTAL_CODE_EXCLUSION = 0x11,
ATSC_DCC_SELECTION_ALPHANUMERIC_POSTAL_CODE_EXCLUSION = 0x12,
ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_NOT_ONE_OR_MORE = 0x15,
ATSC_DCC_SELECTION_DEMOGRAPHIC_CATEGORY_NOT_ALL = 0x16,
ATSC_DCC_SELECTION_GENRE_CATEGORY_NOT_ONE_OR_MORE = 0x17,
ATSC_DCC_SELECTION_GENRE_CATEGORY_NOT_ALL = 0x18,
ATSC_DCC_SELECTION_GEOGRAPHIC_LOCATION_EXCLUSION = 0x1c,
ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_A = 0x20,
ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_B = 0x21,
ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_C = 0x22,
ATSC_DCC_SELECTION_VIEWER_DIRECT_SELECT_D = 0x23,
};
/**
* atsc_dcct_section structure.
*/
struct atsc_dcct_section {
struct atsc_section_psip head;
uint8_t dcc_test_count;
/* struct atsc_dcct_test tests */
/* struct atsc_dcct_section_part2 part2 */
} __ucsi_packed;
struct atsc_dcct_test {
EBIT4(uint32_t dcc_context : 1; ,
uint32_t reserved : 3; ,
uint32_t dcc_from_major_channel_number :10; ,
uint32_t dcc_from_minor_channel_number :10; );
EBIT3(uint32_t reserved1 : 4; ,
uint32_t dcc_to_major_channel_number :10; ,
uint32_t dcc_to_minor_channel_number :10; );
atsctime_t start_time;
atsctime_t end_time;
uint8_t dcc_term_count;
/* struct atsc_dcct_term terms */
/* struct atsc_dcct_test_part2 part2 */
} __ucsi_packed;
struct atsc_dcct_term {
uint8_t dcc_selection_type;
uint64_t dcc_selection_id;
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
struct atsc_dcct_test_part2 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
struct atsc_dcct_section_part2 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
static inline struct atsc_dcct_test *
atsc_dcct_section_tests_first(struct atsc_dcct_section *dcct);
static inline struct atsc_dcct_test *
atsc_dcct_section_tests_next(struct atsc_dcct_section *dcct,
struct atsc_dcct_test *pos,
int idx);
static inline struct atsc_dcct_term *
atsc_dcct_test_terms_first(struct atsc_dcct_test *test);
static inline struct atsc_dcct_term *
atsc_dcct_test_terms_next(struct atsc_dcct_test *test,
struct atsc_dcct_term *pos,
int idx);
/**
* Process an atsc_dcct_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_dcct_section pointer, or NULL on error.
*/
struct atsc_dcct_section *atsc_dcct_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the dcc_subtype field of a dcct.
*
* @param dcct dcct pointer.
* @return The dcc_subtype.
*/
static inline uint8_t atsc_dcct_section_dcc_subtype(struct atsc_dcct_section *dcct)
{
return dcct->head.ext_head.table_id_ext >> 8;
}
/**
* Accessor for the dcc_id field of a dcct.
*
* @param dcct dcct pointer.
* @return The dcc_id.
*/
static inline uint8_t atsc_dcct_section_dcc_id(struct atsc_dcct_section *dcct)
{
return dcct->head.ext_head.table_id_ext & 0xff;
}
/**
* Iterator for the tests field in an atsc_dcct_section.
*
* @param dcct atsc_dcct_section pointer.
* @param pos Variable containing a pointer to the current atsc_dcct_test.
* @param idx Integer used to count which test we are in.
*/
#define atsc_dcct_section_tests_for_each(dcct, pos, idx) \
for ((pos) = atsc_dcct_section_tests_first(dcct), idx=0; \
(pos); \
(pos) = atsc_dcct_section_tests_next(dcct, pos, ++idx))
/**
* Iterator for the terms field in an atsc_dcct_test.
*
* @param test atsc_dcct_test pointer.
* @param pos Variable containing a pointer to the current atsc_dcct_term.
* @param idx Integer used to count which test we are in.
*/
#define atsc_dcct_test_terms_for_each(test, pos, idx) \
for ((pos) = atsc_dcct_test_terms_first(test), idx=0; \
(pos); \
(pos) = atsc_dcct_test_terms_next(test, pos, ++idx))
/**
* Iterator for the descriptors field in a atsc_dcct_term structure.
*
* @param term atsc_dcct_term pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_dcct_term_descriptors_for_each(term, pos) \
for ((pos) = atsc_dcct_term_descriptors_first(term); \
(pos); \
(pos) = atsc_dcct_term_descriptors_next(term, pos))
/**
* Accessor for the part2 field of an atsc_dcct_test.
*
* @param test atsc_dcct_test pointer.
* @return struct atsc_dcct_test_part2 pointer.
*/
static inline struct atsc_dcct_test_part2 *atsc_dcct_test_part2(struct atsc_dcct_test *test)
{
int pos = sizeof(struct atsc_dcct_test);
struct atsc_dcct_term *cur_term;
int idx;
atsc_dcct_test_terms_for_each(test, cur_term, idx) {
pos += sizeof(struct atsc_dcct_term);
pos += cur_term->descriptors_length;
}
return (struct atsc_dcct_test_part2 *) (((uint8_t*) test) + pos);
}
/**
* Iterator for the descriptors field in a atsc_dcct_test_part2 structure.
*
* @param term atsc_dcct_test_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_dcct_test_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_dcct_test_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_dcct_test_part2_descriptors_next(part2, pos))
/**
* Accessor for the part2 field of an atsc_dcct_section.
*
* @param dcct atsc_dcct_section pointer.
* @return struct atsc_dcct_section_part2 pointer.
*/
static inline struct atsc_dcct_section_part2 *atsc_dcct_section_part2(struct atsc_dcct_section *dcct)
{
int pos = sizeof(struct atsc_dcct_section);
struct atsc_dcct_test *cur_test;
int testidx;
atsc_dcct_section_tests_for_each(dcct, cur_test, testidx) {
struct atsc_dcct_test_part2 *part2 = atsc_dcct_test_part2(cur_test);
pos += ((uint8_t*) part2 - (uint8_t*) cur_test);
pos += sizeof(struct atsc_dcct_test_part2);
pos += part2->descriptors_length;
}
return (struct atsc_dcct_section_part2 *) (((uint8_t*) dcct) + pos);
}
/**
* Iterator for the descriptors field in a atsc_dcct_section_part2 structure.
*
* @param part2 atsc_dcct_section_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_dcct_section_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_dcct_section_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_dcct_section_part2_descriptors_next(part2, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_dcct_test *
atsc_dcct_section_tests_first(struct atsc_dcct_section *dcct)
{
size_t pos = sizeof(struct atsc_dcct_section);
if (dcct->dcc_test_count == 0)
return NULL;
return (struct atsc_dcct_test*) (((uint8_t *) dcct) + pos);
}
static inline struct atsc_dcct_test *
atsc_dcct_section_tests_next(struct atsc_dcct_section *dcct,
struct atsc_dcct_test *pos,
int idx)
{
if (idx >= dcct->dcc_test_count)
return NULL;
struct atsc_dcct_test_part2 *part2 = atsc_dcct_test_part2(pos);
int len = sizeof(struct atsc_dcct_test_part2);
len += part2->descriptors_length;
return (struct atsc_dcct_test *) (((uint8_t*) part2) + len);
}
static inline struct atsc_dcct_term *
atsc_dcct_test_terms_first(struct atsc_dcct_test *test)
{
size_t pos = sizeof(struct atsc_dcct_test);
if (test->dcc_term_count == 0)
return NULL;
return (struct atsc_dcct_term*) (((uint8_t *) test) + pos);
}
static inline struct atsc_dcct_term *
atsc_dcct_test_terms_next(struct atsc_dcct_test *test,
struct atsc_dcct_term *pos,
int idx)
{
if (idx >= test->dcc_term_count)
return NULL;
int len = sizeof(struct atsc_dcct_term);
len += pos->descriptors_length;
return (struct atsc_dcct_term *) (((uint8_t*) pos) + len);
}
static inline struct descriptor *
atsc_dcct_term_descriptors_first(struct atsc_dcct_term *term)
{
size_t pos = sizeof(struct atsc_dcct_term);
if (term->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) term) + pos);
}
static inline struct descriptor *
atsc_dcct_term_descriptors_next(struct atsc_dcct_term *term,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) term + sizeof(struct atsc_dcct_term),
term->descriptors_length,
pos);
}
static inline struct descriptor *
atsc_dcct_test_part2_descriptors_first(struct atsc_dcct_test_part2 *part2)
{
size_t pos = sizeof(struct atsc_dcct_test_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_dcct_test_part2_descriptors_next(struct atsc_dcct_test_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dcct_test_part2),
part2->descriptors_length,
pos);
}
static inline struct descriptor *
atsc_dcct_section_part2_descriptors_first(struct atsc_dcct_section_part2 *part2)
{
size_t pos = sizeof(struct atsc_dcct_section_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_dcct_section_part2_descriptors_next(struct atsc_dcct_section_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_dcct_section_part2),
part2->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -28,39 +28,37 @@ extern "C"
#endif
#include <libucsi/endianops.h>
#include <libucsi/atsc/stuffing_descriptor.h>
#include <libucsi/atsc/ac3_descriptor.h>
#include <libucsi/atsc/caption_service_descriptor.h>
#include <libucsi/atsc/component_name_descriptor.h>
#include <libucsi/atsc/content_advisory_descriptor.h>
#include <libucsi/atsc/dcc_arriving_request_descriptor.h>
#include <libucsi/atsc/dcc_departing_request_descriptor.h>
#include <libucsi/atsc/extended_channel_name_descriptor.h>
#include <libucsi/atsc/genre_descriptor.h>
#include <libucsi/atsc/rc_descriptor.h>
#include <libucsi/atsc/service_location_descriptor.h>
#include <libucsi/atsc/time_shifted_service_descriptor.h>
/**
* Enumeration of ATSC descriptor tags.
*/
enum atsc_descriptor_tag {
/* A 52/A describes a
* dtag_atsc_ac3_registration = 0x05, */
/* A90 describes a
* dtag_atsc_association_tag = 0x14, */
dtag_atsc_stuffing = 0x80,
dtag_atsc_ac3_audio = 0x81,
dtag_atsc_caption_service = 0x86,
dtag_atsc_content_advisory = 0x87,
dtag_atsc_ca = 0x88,
dtag_atsc_extended_channel_name = 0xa0,
dtag_atsc_service_location = 0xa1,
dtag_atsc_time_shifted_service = 0xa2,
dtag_atsc_component_name = 0xa3,
dtag_atsc_data_service = 0xa4,
dtag_atsc_pid_count = 0xa5,
dtag_atsc_download = 0xa6,
dtag_atsc_MPE = 0xa7,
dtag_atsc_dcc_departing_request = 0xa8,
dtag_atsc_dcc_arriving_request = 0xa9,
dtag_atsc_redistribution_control = 0xaa,
dtag_atsc_dcc_location_code = 0xab,
dtag_atsc_private_information = 0xad,
dtag_atsc_module_link = 0xb4,
dtag_atsc_crc32 = 0xb5,
dtag_atsc_group_link = 0xb8,
dtag_atsc_content_identifier = 0xb6,
dtag_atsc_genre = 0xab,
};
#ifdef __cplusplus

@ -0,0 +1,71 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/eit_section.h>
struct atsc_eit_section *atsc_eit_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = 0;
size_t len = section_ext_length(&(psip->ext_head));
int idx;
if (len < sizeof(struct atsc_eit_section))
return NULL;
struct atsc_eit_section *eit = (struct atsc_eit_section *) psip;
pos += sizeof(struct atsc_eit_section);
for(idx =0; idx < eit->num_events_in_section; idx++) {
if (len < (pos + sizeof(struct atsc_eit_event)))
return NULL;
struct atsc_eit_event *event = (struct atsc_eit_event *) (buf+pos);
bswap16(buf+pos);
bswap32(buf+pos+2);
bswap32(buf+pos+6);
pos += sizeof(struct atsc_eit_event);
if (len < (pos + event->title_length))
return NULL;
if (atsc_text_validate(buf+pos, event->title_length))
return NULL;
pos += event->title_length;
if (len < (pos + sizeof(struct atsc_eit_event_part2)))
return NULL;
struct atsc_eit_event_part2 *part2 = (struct atsc_eit_event_part2 *) (buf+pos);
bswap16(buf+pos);
pos += sizeof(struct atsc_eit_event_part2);
if (len < (pos + part2->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
}
if (pos != len)
return NULL;
return (struct atsc_eit_section *) psip;
}

@ -0,0 +1,191 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_EIT_SECTION_H
#define _UCSI_ATSC_EIT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
#include <libucsi/atsc/types.h>
/**
* atsc_eit_section structure.
*/
struct atsc_eit_section {
struct atsc_section_psip head;
uint8_t num_events_in_section;
/* struct atsc_eit_event events[] */
} __ucsi_packed;
struct atsc_eit_event {
EBIT2(uint16_t reserved : 2; ,
uint16_t event_id :14; );
atsctime_t start_time;
EBIT4(uint32_t reserved1 : 2; ,
uint32_t ETM_location : 2; ,
uint32_t length_in_seconds :20; ,
uint32_t title_length : 8; );
/* struct atsc_text title_text */
/* struct atsc_eit_event_part2 part2 */
} __ucsi_packed;
struct atsc_eit_event_part2 {
EBIT2(uint16_t reserved : 4; ,
uint16_t descriptors_length :12; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
/**
* Process a atsc_eit_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_eit_section pointer, or NULL on error.
*/
struct atsc_eit_section *atsc_eit_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the source_id field of an EIT.
*
* @param eit EIT pointer.
* @return The source_id .
*/
static inline uint16_t atsc_eit_section_source_id(struct atsc_eit_section *eit)
{
return eit->head.ext_head.table_id_ext;
}
/**
* Iterator for the events field in an atsc_eit_section.
*
* @param eit atsc_eit_section pointer.
* @param pos Variable containing a pointer to the current atsc_eit_event.
* @param idx Integer used to count which event we are in.
*/
#define atsc_eit_section_events_for_each(eit, pos, idx) \
for ((pos) = atsc_eit_section_events_first(eit), idx=0; \
(pos); \
(pos) = atsc_eit_section_events_next(eit, pos, ++idx))
/**
* Accessor for the title_text field of an atsc_eit_event.
*
* @param event atsc_eit_event pointer.
* @return struct atsc_text pointer, or NULL on error.
*/
static inline struct atsc_text *atsc_eit_event_name_title_text(struct atsc_eit_event *event)
{
if (event->title_length == 0)
return NULL;
return (struct atsc_text*)(((uint8_t*) event) + sizeof(struct atsc_eit_event));
}
/**
* Accessor for the part2 field of an atsc_eit_event.
*
* @param event atsc_eit_event pointer.
* @return struct atsc_eit_event_part2 pointer.
*/
static inline struct atsc_eit_event_part2 *atsc_eit_event_part2(struct atsc_eit_event *event)
{
return (struct atsc_eit_event_part2 *)
(((uint8_t*) event) + sizeof(struct atsc_eit_event) + event->title_length);
}
/**
* Iterator for the descriptors field in a atsc_eit_section structure.
*
* @param part2 atsc_eit_event_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_eit_event_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_eit_event_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_eit_event_part2_descriptors_next(part2, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_eit_event *
atsc_eit_section_events_first(struct atsc_eit_section *eit)
{
size_t pos = sizeof(struct atsc_eit_section);
if (eit->num_events_in_section == 0)
return NULL;
return (struct atsc_eit_event*) (((uint8_t *) eit) + pos);
}
static inline struct atsc_eit_event *
atsc_eit_section_events_next(struct atsc_eit_section *eit,
struct atsc_eit_event *pos,
int idx)
{
if (idx >= eit->num_events_in_section)
return NULL;
struct atsc_eit_event_part2 *part2 = atsc_eit_event_part2(pos);
int len = sizeof(struct atsc_eit_event_part2);
len += part2->descriptors_length;
return (struct atsc_eit_event *) (((uint8_t*) part2) + len);
}
static inline struct descriptor *
atsc_eit_event_part2_descriptors_first(struct atsc_eit_event_part2 *part2)
{
size_t pos = sizeof(struct atsc_eit_event_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_eit_event_part2_descriptors_next(struct atsc_eit_event_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_eit_event_part2),
part2->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,42 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/ett_section.h>
#include <libucsi/atsc/types.h>
struct atsc_ett_section *atsc_ett_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = sizeof(struct atsc_section_psip);
size_t len = section_ext_length(&(psip->ext_head));
if (len < sizeof(struct atsc_ett_section))
return NULL;
bswap32(buf + pos);
pos += 4;
if (atsc_text_validate(buf + pos,
section_ext_length(&psip->ext_head) - sizeof(struct atsc_ett_section)))
return NULL;
return (struct atsc_ett_section *) psip;
}

@ -0,0 +1,91 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_ETT_SECTION_H
#define _UCSI_ATSC_ETT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
enum atsc_etm_type {
ATSC_ETM_CHANNEL = 0x00,
ATSC_ETM_EVENT = 0x02,
};
/**
* atsc_ett_section structure.
*/
struct atsc_ett_section {
struct atsc_section_psip head;
EBIT3(uint32_t ETM_source_id :16; ,
uint32_t ETM_sub_id :14; ,
uint32_t ETM_type : 2; );
/* struct atsc_text extended_text_message */
} __ucsi_packed;
/**
* Process a atsc_ett_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_ett_section pointer, or NULL on error.
*/
struct atsc_ett_section *atsc_ett_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the extended_text_message part of an atsc_ett_section.
*
* @param ett atsc_ett_section pointer.
* @return atsc_text pointer, or NULL on error.
*/
static inline struct atsc_text*
atsc_ett_section_extended_text_message(struct atsc_ett_section *ett)
{
int pos = sizeof(struct atsc_ett_section);
int len = section_ext_length(&ett->head.ext_head) - sizeof(struct atsc_ett_section);
if (len == 0)
return NULL;
return (struct atsc_text*)(((uint8_t*) ett) + pos);
}
/**
* Accessor for the extended_text_message part of an atsc_ett_section.
*
* @param ett atsc_ett_section pointer.
* @return The length.
*/
static inline int
atsc_ett_section_extended_text_message_length(struct atsc_ett_section *ett)
{
return section_ext_length(&ett->head.ext_head) - sizeof(struct atsc_ett_section);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,92 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR
#define _UCSI_ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
#include <libucsi/atsc/types.h>
/**
* atsc_extended_channel_name_descriptor structure.
*/
struct atsc_extended_channel_name_descriptor {
struct descriptor d;
/* struct atsc_text text[] */
} __ucsi_packed;
/**
* Process an atsc_extended_channel_name_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_extended_channel_name_descriptor pointer, or NULL on error.
*/
static inline struct atsc_extended_channel_name_descriptor*
atsc_extended_channel_name_descriptor_codec(struct descriptor* d)
{
if (atsc_text_validate(((uint8_t*) d) + sizeof(struct atsc_extended_channel_name_descriptor),
d->len))
return NULL;
return (struct atsc_extended_channel_name_descriptor*) d;
}
/**
* Accessor for the text field of an atsc_extended_channel_name_descriptor.
*
* @param d atsc_extended_channel_name_descriptor pointer.
* @return Pointer to the atsc_text data, or NULL on error.
*/
static inline struct atsc_text*
atsc_extended_channel_name_descriptor_text(struct atsc_extended_channel_name_descriptor *d)
{
uint8_t *txt = ((uint8_t*) d) + sizeof(struct atsc_extended_channel_name_descriptor);
return (struct atsc_text*) txt;
}
/**
* Accessor for the length of the text field of an atsc_extended_channel_name_descriptor.
*
* @param d atsc_extended_channel_name_descriptor pointer.
* @return The length in bytes.
*/
static inline int
atsc_extended_channel_name_descriptor_text_length(struct
atsc_extended_channel_name_descriptor *d)
{
return d->d.len;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,82 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_GENRE_DESCRIPTOR
#define _UCSI_ATSC_GENRE_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
/**
* atsc_genre_descriptor structure.
*/
struct atsc_genre_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 3; ,
uint8_t attribute_count : 5; );
/* uint8_t attributes[] */
} __ucsi_packed;
/**
* Process an atsc_genre_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_genre_descriptor pointer, or NULL on error.
*/
static inline struct atsc_genre_descriptor*
atsc_genre_descriptor_codec(struct descriptor* d)
{
struct atsc_genre_descriptor *ret =
(struct atsc_genre_descriptor *) d;
if (d->len < 1)
return NULL;
if (d->len != (1 + ret->attribute_count))
return NULL;
return (struct atsc_genre_descriptor*) d;
}
/**
* Accessor for the attributes field of an atsc_genre_descriptor.
*
* @param d atsc_genre_descriptor pointer.
* @return Pointer to the attributes.
*/
static inline uint8_t*
atsc_genre_descriptor_attributes(struct atsc_genre_descriptor *d)
{
return ((uint8_t*) d) + sizeof(struct atsc_genre_descriptor);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,76 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/mgt_section.h>
struct atsc_mgt_section *atsc_mgt_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = sizeof(struct atsc_section_psip);
size_t len = section_ext_length(&(psip->ext_head));
struct atsc_mgt_section *mgt = (struct atsc_mgt_section *) psip;
int i;
if (len < sizeof(struct atsc_mgt_section))
return NULL;
bswap16(buf + pos);
pos += 2;
// we cannot use the tables_defined value here because of the braindead ATSC spec!
for(i=0; i < mgt->tables_defined; i++) {
// we think we're still in the tables - process as normal
if ((pos + sizeof(struct atsc_mgt_table)) > len)
return NULL;
struct atsc_mgt_table *table = (struct atsc_mgt_table *) (buf+pos);
bswap16(buf+pos);
bswap16(buf+pos+2);
bswap32(buf+pos+5);
bswap16(buf+pos+9);
pos += sizeof(struct atsc_mgt_table);
if ((pos + table->table_type_descriptors_length) > len)
return NULL;
if (verify_descriptors(buf + pos, table->table_type_descriptors_length))
return NULL;
pos += table->table_type_descriptors_length;
}
if ((pos + sizeof(struct atsc_mgt_section_part2)) > len)
return NULL;
struct atsc_mgt_section_part2 *part2 = (struct atsc_mgt_section_part2 *) (buf+pos);
bswap16(buf+pos);
pos += sizeof(struct atsc_mgt_section_part2);
if ((pos + part2->descriptors_length) > len)
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
if (pos != len)
return NULL;
return (struct atsc_mgt_section *) psip;
}

@ -0,0 +1,215 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_MGT_SECTION_H
#define _UCSI_ATSC_MGT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
enum atsc_mgt_section_table_type {
ATSC_MGT_TABLE_TYPE_TVCT_CURRENT = 0,
ATSC_MGT_TABLE_TYPE_TVCT_NEXT = 1,
ATSC_MGT_TABLE_TYPE_CVCT_CURRENT = 2,
ATSC_MGT_TABLE_TYPE_CVCT_NEXT = 3,
ATSC_MGT_TABLE_TYPE_CHANNEL_ETT = 4,
ATSC_MGT_TABLE_TYPE_DCCSCT = 5,
};
/**
* atsc_mgt_section structure.
*/
struct atsc_mgt_section {
struct atsc_section_psip head;
uint16_t tables_defined;
/* struct atsc_mgt_table tables[] */
/* struct atsc_mgt_section_part2 part2 */
} __ucsi_packed;
struct atsc_mgt_table {
uint16_t table_type;
EBIT2(uint16_t reserved : 3; ,
uint16_t table_type_PID :13; );
EBIT2(uint8_t reserved1 : 3; ,
uint8_t table_type_version_number : 5; );
uint32_t number_bytes;
EBIT2(uint16_t reserved2 : 4; ,
uint16_t table_type_descriptors_length :12; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
struct atsc_mgt_section_part2 {
EBIT2(uint16_t reserved : 4; ,
uint16_t descriptors_length :12; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
static inline struct atsc_mgt_table * atsc_mgt_section_tables_first(struct atsc_mgt_section *mgt);
static inline struct atsc_mgt_table *
atsc_mgt_section_tables_next(struct atsc_mgt_section *mgt, struct atsc_mgt_table *pos, int idx);
/**
* Process a atsc_mgt_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_mgt_section pointer, or NULL on error.
*/
struct atsc_mgt_section *atsc_mgt_section_codec(struct atsc_section_psip *section);
/**
* Iterator for the tables field in an atsc_mgt_section.
*
* @param mgt atsc_mgt_section pointer.
* @param pos Variable containing a pointer to the current atsc_mgt_table.
* @param idx Integer used to count which table we in.
*/
#define atsc_mgt_section_tables_for_each(mgt, pos, idx) \
for ((pos) = atsc_mgt_section_tables_first(mgt), idx=0; \
(pos); \
(pos) = atsc_mgt_section_tables_next(mgt, pos, ++idx))
/**
* Iterator for the descriptors field in a atsc_mgt_table structure.
*
* @param table atsc_mgt_table pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_mgt_table_descriptors_for_each(table, pos) \
for ((pos) = atsc_mgt_table_descriptors_first(table); \
(pos); \
(pos) = atsc_mgt_table_descriptors_next(table, pos))
/**
* Accessor for the second part of an atsc_mgt_section.
*
* @param mgt atsc_mgt_section pointer.
* @return atsc_mgt_section_part2 pointer.
*/
static inline struct atsc_mgt_section_part2 *
atsc_mgt_section_part2(struct atsc_mgt_section *mgt)
{
int pos = sizeof(struct atsc_mgt_section);
struct atsc_mgt_table *cur_table;
int idx;
atsc_mgt_section_tables_for_each(mgt, cur_table, idx) {
pos += sizeof(struct atsc_mgt_table);
pos += cur_table->table_type_descriptors_length;
}
return (struct atsc_mgt_section_part2 *) (((uint8_t*) mgt) + pos);
}
/**
* Iterator for the descriptors field in a atsc_mgt_section structure.
*
* @param part2 atsc_mgt_section_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_mgt_section_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_mgt_section_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_mgt_section_part2_descriptors_next(part2, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_mgt_table *
atsc_mgt_section_tables_first(struct atsc_mgt_section *mgt)
{
size_t pos = sizeof(struct atsc_mgt_section);
if (mgt->tables_defined == 0)
return NULL;
return (struct atsc_mgt_table*) (((uint8_t *) mgt) + pos);
}
static inline struct atsc_mgt_table *
atsc_mgt_section_tables_next(struct atsc_mgt_section *mgt,
struct atsc_mgt_table *pos,
int idx)
{
if (idx >= mgt->tables_defined)
return NULL;
return (struct atsc_mgt_table *)
(((uint8_t*) pos) + sizeof(struct atsc_mgt_table) + pos->table_type_descriptors_length);
}
static inline struct descriptor *
atsc_mgt_table_descriptors_first(struct atsc_mgt_table *table)
{
size_t pos = sizeof(struct atsc_mgt_table);
if (table->table_type_descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) table) + pos);
}
static inline struct descriptor *
atsc_mgt_table_descriptors_next(struct atsc_mgt_table *table,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) table + sizeof(struct atsc_mgt_table),
table->table_type_descriptors_length,
pos);
}
static inline struct descriptor *
atsc_mgt_section_part2_descriptors_first(struct atsc_mgt_section_part2 *part2)
{
size_t pos = sizeof(struct atsc_mgt_section_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_mgt_section_part2_descriptors_next(struct atsc_mgt_section_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_mgt_section_part2),
part2->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,83 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_RC_DESCRIPTOR
#define _UCSI_ATSC_RC_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
/**
* atsc_rc_descriptor structure.
*/
struct atsc_rc_descriptor {
struct descriptor d;
/* uint8_t info[] */
} __ucsi_packed;
/**
* Process an atsc_rc_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_rc_descriptor pointer, or NULL on error.
*/
static inline struct atsc_rc_descriptor*
atsc_rc_descriptor_codec(struct descriptor* d)
{
return (struct atsc_rc_descriptor*) d;
}
/**
* Accessor for the info field of an atsc_rc_descriptor.
*
* @param d atsc_rc_descriptor pointer.
* @return Pointer to the atsc_text data.
*/
static inline uint8_t*
atsc_rc_descriptor_info(struct atsc_rc_descriptor *d)
{
return ((uint8_t*) d) + sizeof(struct atsc_rc_descriptor);
}
/**
* Accessor for the length of the info field of an atsc_rc_descriptor.
*
* @param d atsc_rc_descriptor pointer.
* @return The length
*/
static inline int
atsc_rc_descriptor_info_length(struct atsc_rc_descriptor *d)
{
return d->d.len;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,108 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/rrt_section.h>
struct atsc_rrt_section *atsc_rrt_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = 0;
size_t len = section_ext_length(&(psip->ext_head));
int idx;
int vidx;
struct atsc_rrt_section *rrt = (struct atsc_rrt_section *) psip;
if (len < sizeof(struct atsc_rrt_section))
return NULL;
pos += sizeof(struct atsc_rrt_section);
if (len < (pos + rrt->rating_region_name_length))
return NULL;
if (atsc_text_validate(buf+pos, rrt->rating_region_name_length))
return NULL;
pos += rrt->rating_region_name_length;
if (len < (pos + sizeof(struct atsc_rrt_section_part2)))
return NULL;
struct atsc_rrt_section_part2 *rrtpart2 = (struct atsc_rrt_section_part2 *) (buf+pos);
pos += sizeof(struct atsc_rrt_section_part2);
for(idx =0; idx < rrtpart2->dimensions_defined; idx++) {
if (len < (pos + sizeof(struct atsc_rrt_dimension)))
return NULL;
struct atsc_rrt_dimension *dimension = (struct atsc_rrt_dimension *) (buf+pos);
pos += sizeof(struct atsc_rrt_dimension);
if (len < (pos + dimension->dimension_name_length))
return NULL;
if (atsc_text_validate(buf+pos, dimension->dimension_name_length))
return NULL;
pos += dimension->dimension_name_length;
if (len < (pos + sizeof(struct atsc_rrt_dimension_part2)))
return NULL;
struct atsc_rrt_dimension_part2 *dpart2 = (struct atsc_rrt_dimension_part2 *) (buf+pos);
pos += sizeof(struct atsc_rrt_dimension_part2);
for(vidx =0; vidx < dpart2->values_defined; vidx++) {
if (len < (pos + sizeof(struct atsc_rrt_dimension_value)))
return NULL;
struct atsc_rrt_dimension_value *value = (struct atsc_rrt_dimension_value *) (buf+pos);
pos += sizeof(struct atsc_rrt_dimension_value);
if (len < (pos + value->abbrev_rating_value_length))
return NULL;
if (atsc_text_validate(buf+pos, value->abbrev_rating_value_length))
return NULL;
pos += value->abbrev_rating_value_length;
if (len < (pos + sizeof(struct atsc_rrt_dimension_value_part2)))
return NULL;
struct atsc_rrt_dimension_value_part2 *vpart2 =
(struct atsc_rrt_dimension_value_part2 *) (buf+pos);
pos += sizeof(struct atsc_rrt_dimension_value_part2);
if (len < (pos + vpart2->rating_value_length))
return NULL;
if (atsc_text_validate(buf+pos, vpart2->rating_value_length))
return NULL;
pos+= vpart2->rating_value_length;
}
}
if (len < (pos + sizeof(struct atsc_rrt_section_part3)))
return NULL;
struct atsc_rrt_section_part3 *part3 = (struct atsc_rrt_section_part3 *) (buf+pos);
pos += sizeof(struct atsc_rrt_section_part3);
if (len < (pos + part3->descriptors_length))
return NULL;
if (verify_descriptors(buf + pos, part3->descriptors_length))
return NULL;
pos += part3->descriptors_length;
if (pos != len)
return NULL;
return (struct atsc_rrt_section *) psip;
}

@ -0,0 +1,379 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_RRT_SECTION_H
#define _UCSI_ATSC_RRT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
#include <libucsi/atsc/types.h>
/**
* atsc_rrt_section structure.
*/
struct atsc_rrt_section {
struct atsc_section_psip head;
uint8_t rating_region_name_length;
/* struct atsc_text rating_region_name_text */
/* struct atsc_rrt_section_part2 part2 */
} __ucsi_packed;
struct atsc_rrt_section_part2 {
uint8_t dimensions_defined;
/* struct atsc_rrt_dimension dimensions[] */
/* struct atsc_rrt_section_part3 part3 */
} __ucsi_packed;
struct atsc_rrt_dimension {
uint8_t dimension_name_length;
/* struct atsc_text dimension_name_text */
/* struct atsc_rrt_dimension_part2 part2 */
} __ucsi_packed;
struct atsc_rrt_dimension_part2 {
EBIT3(uint8_t reserved : 3; ,
uint8_t graduated_scale : 1; ,
uint8_t values_defined : 4; );
/* struct atsc_rrt_dimension_value values[] */
} __ucsi_packed;
struct atsc_rrt_dimension_value {
uint8_t abbrev_rating_value_length;
/* struct atsc_text abbrev_rating_value_text */
/* struct atsc_rrt_dimension_value_part2 */
} __ucsi_packed;
struct atsc_rrt_dimension_value_part2 {
uint8_t rating_value_length;
/* struct atsc_text rating_value_text */
} __ucsi_packed;
struct atsc_rrt_section_part3 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
static inline struct atsc_rrt_dimension *
atsc_rrt_section_dimensions_first(struct atsc_rrt_section_part2 *part2);
static inline struct atsc_rrt_dimension *
atsc_rrt_section_dimensions_next(struct atsc_rrt_section_part2 *part2,
struct atsc_rrt_dimension *pos,
int idx);
static inline struct atsc_rrt_dimension_value *
atsc_rrt_dimension_part2_values_first(struct atsc_rrt_dimension_part2 *part2);
static inline struct atsc_rrt_dimension_value *
atsc_rrt_dimension_part2_values_next(struct atsc_rrt_dimension_part2 *part2,
struct atsc_rrt_dimension_value *pos,
int idx);
/**
* Process a atsc_rrt_section.
*
* @param section Pointer to anj atsc_section_psip structure.
* @return atsc_rrt_section pointer, or NULL on error.
*/
struct atsc_rrt_section *atsc_rrt_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the rating_region field of an RRT.
*
* @param rrt RRT pointer.
* @return The transport_stream_id.
*/
static inline uint8_t atsc_rrt_section_rating_region(struct atsc_rrt_section *rrt)
{
return rrt->head.ext_head.table_id_ext & 0xff;
}
/**
* Accessor for the rating_region_name_text field of an RRT.
*
* @param rrt RRT pointer.
* @return struct atsc_text pointer, or NULL.
*/
static inline struct atsc_text *atsc_rrt_section_rating_region_name_text(struct atsc_rrt_section *rrt)
{
if (rrt->rating_region_name_length == 0)
return NULL;
return (struct atsc_text*)(((uint8_t*) rrt) + sizeof(struct atsc_rrt_section));
}
/**
* Accessor for the part2 field of an RRT.
*
* @param rrt RRT pointer.
* @return struct atsc_rrt_section_part2 pointer.
*/
static inline struct atsc_rrt_section_part2 *atsc_rrt_section_part2(struct atsc_rrt_section *rrt)
{
return (struct atsc_rrt_section_part2 *)
(((uint8_t*) rrt) + sizeof(struct atsc_rrt_section) +
rrt->rating_region_name_length);
}
/**
* Iterator for the dimensions field in an atsc_rrt_section_part2.
*
* @param rrt atsc_rrt_section pointer.
* @param pos Variable containing a pointer to the current atsc_rrt_dimension.
* @param idx Integer used to count which dimension we are in.
*/
#define atsc_rrt_section_dimensions_for_each(rrt, pos, idx) \
for ((pos) = atsc_rrt_section_dimensions_first(rrt), idx=0; \
(pos); \
(pos) = atsc_rrt_section_dimensions_next(rrt, pos, ++idx))
/**
* Accessor for the dimension_name_text field of an atsc_rrt_dimension.
*
* @param dimension atsc_rrt_dimension pointer.
* @return struct atsc_text pointer, or NULL on error.
*/
static inline struct atsc_text *atsc_rrt_dimension_name_text(struct atsc_rrt_dimension *dimension)
{
if (dimension->dimension_name_length == 0)
return NULL;
return (struct atsc_text*)(((uint8_t*) dimension) + sizeof(struct atsc_rrt_dimension));
}
/**
* Accessor for the part2 field of an atsc_rrt_dimension.
*
* @param dimension atsc_rrt_dimension pointer.
* @return struct atsc_rrt_dimension_part2 pointer.
*/
static inline struct atsc_rrt_dimension_part2 *atsc_rrt_dimension_part2(struct atsc_rrt_dimension *dimension)
{
return (struct atsc_rrt_dimension_part2 *)
(((uint8_t*) dimension) +
sizeof(struct atsc_rrt_dimension) +
dimension->dimension_name_length);
}
/**
* Iterator for the values field in a atsc_rrt_dimension_part2 structure.
*
* @param part2 atsc_rrt_dimension_part2 pointer.
* @param pos Variable containing a pointer to the current value.
* @param idx Integer used to count which value we are in
*/
#define atsc_rrt_dimension_part2_values_for_each(part2, pos, idx) \
for ((pos) = atsc_rrt_dimension_part2_values_first(part2), idx=0; \
(pos); \
(pos) = atsc_rrt_dimension_part2_values_next(part2, pos, ++idx))
/**
* Accessor for the dimension_name_text field of an atsc_rrt_dimension.
*
* @param dimension atsc_rrt_dimension pointer.
* @return struct atsc_text pointer.
*/
static inline struct atsc_text *
atsc_rrt_dimension_value_abbrev_rating_value_text(struct atsc_rrt_dimension_value *value)
{
if (value->abbrev_rating_value_length == 0)
return NULL;
return (struct atsc_text*)(((uint8_t*) value) + sizeof(struct atsc_rrt_dimension_value));
}
/**
* Accessor for the part2 field of an atsc_rrt_dimension_value.
*
* @param value atsc_rrt_dimension_value pointer.
* @return struct atsc_rrt_dimension_value_part2 pointer.
*/
static inline struct atsc_rrt_dimension_value_part2 *atsc_rrt_dimension_value_part2(struct atsc_rrt_dimension_value *value)
{
return (struct atsc_rrt_dimension_value_part2 *)
(((uint8_t*) value) +
sizeof(struct atsc_rrt_dimension_value) +
value->abbrev_rating_value_length);
}
/**
* Accessor for the rating_value_text field of an atsc_rrt_dimension_value_part2.
*
* @param part2 atsc_rrt_dimension_value_part2 pointer.
* @return struct atsc_text pointer.
*/
static inline struct atsc_text *atsc_rrt_dimension_value_part2_rating_value_text(struct atsc_rrt_dimension_value_part2 *part2)
{
if (part2->rating_value_length == 0)
return NULL;
return (struct atsc_text*)(((uint8_t*) part2) + sizeof(struct atsc_rrt_dimension_value_part2));
}
/**
* Accessor for the third part of an atsc_rrt_section.
*
* @param part2 atsc_rrt_section_part2 pointer.
* @return atsc_rrt_section_part3 pointer.
*/
static inline struct atsc_rrt_section_part3 *
atsc_rrt_section_part3(struct atsc_rrt_section_part2 *part2)
{
int pos = sizeof(struct atsc_rrt_section_part2);
struct atsc_rrt_dimension *cur_dimension;
int idx;
atsc_rrt_section_dimensions_for_each(part2, cur_dimension, idx) {
pos += sizeof(struct atsc_rrt_dimension);
pos += cur_dimension->dimension_name_length;
pos += sizeof(struct atsc_rrt_dimension_part2);
// now we need to iterate over the values. yuck
struct atsc_rrt_dimension_part2 *dpart2 = atsc_rrt_dimension_part2(cur_dimension);
struct atsc_rrt_dimension_value *cur_value;
int vidx;
atsc_rrt_dimension_part2_values_for_each(dpart2, cur_value, vidx) {
pos += sizeof(struct atsc_rrt_dimension_value);
pos += cur_value->abbrev_rating_value_length;
struct atsc_rrt_dimension_value_part2 *vpart2 = atsc_rrt_dimension_value_part2(cur_value);
pos += sizeof(struct atsc_rrt_dimension_value_part2);
pos += vpart2->rating_value_length;
}
}
return (struct atsc_rrt_section_part3 *) (((uint8_t*) part2) + pos);
}
/**
* Iterator for the descriptors field in a atsc_rrt_section structure.
*
* @param part3 atsc_rrt_section_part3 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_rrt_section_part3_descriptors_for_each(part3, pos) \
for ((pos) = atsc_rrt_section_part3_descriptors_first(part3); \
(pos); \
(pos) = atsc_rrt_section_part3_descriptors_next(part3, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_rrt_dimension *
atsc_rrt_section_dimensions_first(struct atsc_rrt_section_part2 *part2)
{
size_t pos = sizeof(struct atsc_rrt_section_part2);
if (part2->dimensions_defined == 0)
return NULL;
return (struct atsc_rrt_dimension*) (((uint8_t *) part2) + pos);
}
static inline struct atsc_rrt_dimension *
atsc_rrt_section_dimensions_next(struct atsc_rrt_section_part2 *part2,
struct atsc_rrt_dimension *pos,
int idx)
{
if (idx >= part2->dimensions_defined)
return NULL;
struct atsc_rrt_dimension_part2 *dpart2 = atsc_rrt_dimension_part2(pos);
int len = sizeof(struct atsc_rrt_dimension_part2);
// now we need to iterate over the values. yuck
struct atsc_rrt_dimension_value *cur_value;
int vidx;
atsc_rrt_dimension_part2_values_for_each(dpart2, cur_value, vidx) {
len += sizeof(struct atsc_rrt_dimension_value);
len += cur_value->abbrev_rating_value_length;
struct atsc_rrt_dimension_value_part2 *vpart2 = atsc_rrt_dimension_value_part2(cur_value);
len += sizeof(struct atsc_rrt_dimension_value_part2);
len += vpart2->rating_value_length;
}
return (struct atsc_rrt_dimension *) (((uint8_t*) dpart2) + len);
}
static inline struct atsc_rrt_dimension_value *
atsc_rrt_dimension_part2_values_first(struct atsc_rrt_dimension_part2 *part2)
{
size_t pos = sizeof(struct atsc_rrt_dimension_part2);
if (part2->values_defined == 0)
return NULL;
return (struct atsc_rrt_dimension_value*) (((uint8_t *) part2) + pos);
}
static inline struct atsc_rrt_dimension_value *
atsc_rrt_dimension_part2_values_next(struct atsc_rrt_dimension_part2 *part2,
struct atsc_rrt_dimension_value *pos,
int idx)
{
if (idx >= part2->values_defined)
return NULL;
struct atsc_rrt_dimension_value_part2 *vpart2 = atsc_rrt_dimension_value_part2(pos);
int len = sizeof(struct atsc_rrt_dimension_value_part2);
len += vpart2->rating_value_length;
return (struct atsc_rrt_dimension_value *) (((uint8_t*) vpart2) + len);
}
static inline struct descriptor *
atsc_rrt_section_part3_descriptors_first(struct atsc_rrt_section_part3 *part3)
{
size_t pos = sizeof(struct atsc_rrt_section_part3);
if (part3->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part3) + pos);
}
static inline struct descriptor *
atsc_rrt_section_part3_descriptors_next(struct atsc_rrt_section_part3 *part3,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part3 + sizeof(struct atsc_rrt_section_part3),
part3->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -19,6 +19,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/section.h>
#include <libucsi/atsc/mgt_section.h>
#include <libucsi/atsc/tvct_section.h>
#include <libucsi/atsc/cvct_section.h>
#include <libucsi/atsc/rrt_section.h>
#include <libucsi/atsc/eit_section.h>
#include <libucsi/atsc/ett_section.h>
#include <libucsi/atsc/stt_section.h>
#include <libucsi/atsc/dcct_section.h>
#include <libucsi/atsc/dccsct_section.h>
#ifndef _UCSI_ATSC_SECTION_H
#define _UCSI_ATSC_SECTION_H 1
@ -27,40 +38,44 @@ extern "C"
{
#endif
#define ATSC_BASE_PID 0x1ffb
/**
* Enumeration of ATSC section tags.
*/
enum atsc_section_tag {
/* 0xC0-0xC6 [ATSC coordinated values which are defined in other standards.] */
stag_atsc_master_guide = 0xc7,
stag_atsc_master_guide = 0xc7,
stag_atsc_terrestrial_virtual_channel = 0xc8,
stag_atsc_cable_virtual_channel = 0xc9,
stag_atsc_rating_region = 0xca,
stag_atsc_event_informationen = 0xcb,
stag_atsc_extended_text = 0xcc,
stag_atsc_cable_virtual_channel = 0xc9,
stag_atsc_rating_region = 0xca,
stag_atsc_event_information = 0xcb,
stag_atsc_extended_text = 0xcc,
stag_atsc_system_time = 0xcd,
};
stag_atsc_data_event = 0xce,
stag_atsc_data_service = 0xcf,
stag_atsc_network_resources = 0xd1,
stag_atsc_long_term_serivce = 0xd2,
/* identical to DVB/ISO ?
0x3F DSM-CC Addressable Section Table
0x3B DSM-CC Section Table
0x3C DSM-CC Section Table */
/* 0xCE-0xD2 [ATSC coordinated values which are defined in other standards.] */
stag_atsc_directed_channel_change = 0xd3,
stag_atsc_directed_channel_change_selection_code = 0xd4,
/**
* ATSC specific PSIP section structure.
*/
struct atsc_section_psip {
struct section_ext ext_head;
uint8_t protocol_version;
} __ucsi_packed;
/* 0xD5-0xDF [ATSC coordinated values which are defined in other standards.] */
stag_atsc_aggregate_event_information = 0xd6,
stag_atsc_aggregate_extended_text = 0xd7,
stag_atsc_satellite_virtual_channel = 0xda,
/**
* Decode a PSIP section structure.
*
* @param section_ext Pointer to the processed section_ext structure.
* @return Pointer to the parsed section_psip structure, or NULL if invalid.
*/
static inline struct atsc_section_psip *atsc_section_psip_decode(struct section_ext *section_ext)
{
size_t len = section_ext_length(section_ext);
if (len < sizeof(struct atsc_section_psip)) {
return NULL;
}
/* 0xE0-0xE5 [Used in other systems] */
/* 0xE6-0xFE [Reserved for future ATSC use] */
};
return (struct atsc_section_psip *) section_ext;
}
#ifdef __cplusplus
}

@ -0,0 +1,141 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_SERVICE_LOCATION_DESCRIPTOR
#define _UCSI_ATSC_SERVICE_LOCATION_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
enum atsc_stream_types {
ATSC_STREAM_TYPE_VIDEO = 0x02,
ATSC_STREAM_TYPE_AUDIO = 0x81,
};
/**
* atsc_service_location_descriptor structure.
*/
struct atsc_service_location_descriptor {
struct descriptor d;
EBIT2(uint16_t reserved : 3; ,
uint16_t PCR_PID :13; );
uint8_t number_elements;
/* struct atsc_service_location_element elements[] */
} __ucsi_packed;
/**
* An entry in the elements field of an atsc_service_location_descriptor.
*/
struct atsc_caption_service_location_element {
uint8_t stream_type;
EBIT2(uint16_t reserved : 3; ,
uint16_t elementary_PID :13; );
iso639lang_t language_code;
} __ucsi_packed;
/**
* Process an atsc_service_location_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_service_location_descriptor pointer, or NULL on error.
*/
static inline struct atsc_service_location_descriptor*
atsc_service_location_descriptor_codec(struct descriptor* d)
{
struct atsc_service_location_descriptor *ret =
(struct atsc_service_location_descriptor *) d;
uint8_t *buf = (uint8_t*) d + 2;
int pos = 0;
int idx;
if (d->len < 3)
return NULL;
bswap16(buf + pos);
pos+=3;
for(idx = 0; idx < ret->number_elements; idx++) {
if (d->len < (pos + sizeof(struct atsc_caption_service_entry)))
return NULL;
bswap16(buf+pos+1);
pos += sizeof(struct atsc_caption_service_entry);
}
return (struct atsc_service_location_descriptor*) d;
}
/**
* Iterator for elements field of a atsc_service_location_descriptor.
*
* @param d atsc_service_location_descriptor pointer.
* @param pos Variable holding a pointer to the current atsc_service_location_element.
* @param idx Integer used to count which dimension we are in.
*/
#define atsc_service_location_descriptor_elements_for_each(d, pos, idx) \
for ((pos) = atsc_service_location_descriptor_elements_first(d), idx=0; \
(pos); \
(pos) = atsc_service_location_descriptor_elements_next(d, pos, ++idx))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_caption_service_location_element*
atsc_service_location_descriptor_elements_first(struct atsc_service_location_descriptor *d)
{
if (d->number_elements == 0)
return NULL;
return (struct atsc_caption_service_location_element *)
((uint8_t*) d + sizeof(struct atsc_service_location_descriptor));
}
static inline struct atsc_caption_service_location_element*
atsc_service_location_descriptor_elements_next(struct atsc_service_location_descriptor *d,
struct atsc_caption_service_location_element *pos,
int idx)
{
uint8_t *next = (uint8_t *) pos + sizeof(struct atsc_caption_service_location_element);
if (idx >= d->number_elements)
return NULL;
return (struct atsc_caption_service_location_element *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,42 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/stt_section.h>
struct atsc_stt_section *atsc_stt_section_codec(struct atsc_section_psip *psip)
{
uint8_t *buf = (uint8_t *) psip;
size_t pos = sizeof(struct atsc_section_psip);
size_t len = section_ext_length(&(psip->ext_head));
if (len < sizeof(struct atsc_stt_section))
return NULL;
bswap32(buf + pos);
pos += 5;
bswap16(buf + pos);
pos += 2;
if (verify_descriptors(buf + pos, len - sizeof(struct atsc_stt_section)))
return NULL;
return (struct atsc_stt_section *) psip;
}

@ -0,0 +1,105 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_STT_SECTION_H
#define _UCSI_ATSC_STT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
#include <libucsi/atsc/types.h>
/**
* atsc_stt_section structure.
*/
struct atsc_stt_section {
struct atsc_section_psip head;
atsctime_t system_time;
uint8_t gps_utc_offset;
EBIT4(uint16_t DS_status : 1; ,
uint16_t reserved : 2; ,
uint16_t DS_day_of_month : 5; ,
uint16_t DS_hour : 8; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
/**
* Process a atsc_stt_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_stt_section pointer, or NULL on error.
*/
struct atsc_stt_section *atsc_stt_section_codec(struct atsc_section_psip *section);
/**
* Iterator for the services field in a atsc_stt_section.
*
* @param stt atsc_stt_section pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_stt_section_descriptors_for_each(stt, pos) \
for ((pos) = atsc_stt_section_descriptors_first(stt); \
(pos); \
(pos) = atsc_stt_section_descriptors_next(stt, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct descriptor *
atsc_stt_section_descriptors_first(struct atsc_stt_section *stt)
{
size_t pos = sizeof(struct atsc_stt_section);
if (pos >= section_ext_length(&stt->head.ext_head))
return NULL;
return (struct descriptor*) ((uint8_t *) stt + pos);
}
static inline struct descriptor *
atsc_stt_section_descriptors_next(struct atsc_stt_section *stt,
struct descriptor *pos)
{
int len = section_ext_length(&stt->head.ext_head);
len -= sizeof(struct atsc_stt_section);
return next_descriptor((uint8_t*) stt + sizeof(struct atsc_stt_section),
len,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,82 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_atsc@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_STUFFING_DESCRIPTOR
#define _UCSI_ATSC_STUFFING_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
/**
* atsc_stuffing_descriptor.
*/
struct atsc_stuffing_descriptor {
struct descriptor d;
/* uint8_t data[] */
} __ucsi_packed;
/**
* Process a atsc_stuffing_descriptor.
*
* @param d Generic descriptor structure.
* @return atsc_stuffing_descriptor pointer, or NULL on error.
*/
static inline struct atsc_stuffing_descriptor*
atsc_stuffing_descriptor_codec(struct descriptor* d)
{
return (struct atsc_stuffing_descriptor*) d;
}
/**
* Retrieve a pointer to the data field of a atsc_stuffing_descriptor.
*
* @param d atsc_stuffing_descriptor pointer.
* @return Pointer to the field.
*/
static inline uint8_t *
atsc_stuffing_descriptor_data(struct atsc_stuffing_descriptor *d)
{
return (uint8_t *) d + sizeof(struct atsc_stuffing_descriptor);
}
/**
* Calculate length of the data field of a atsc_stuffing_descriptor.
*
* @param d atsc_stuffing_descriptor pointer.
* @return The length in bytes.
*/
static inline int
atsc_stuffing_descriptor_data_length(struct atsc_stuffing_descriptor *d)
{
return d->d.len;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,136 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_TIME_SHIFTED_SERVICE_DESCRIPTOR
#define _UCSI_ATSC_TIME_SHIFTED_SERVICE_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
#include <libucsi/types.h>
/**
* atsc_time_shifted_service_descriptor structure.
*/
struct atsc_time_shifted_service_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 3; ,
uint8_t number_of_services : 5; );
/* struct atsc_time_shifted_service services[] */
} __ucsi_packed;
/**
* An entry in the services field of an atsc_time_shifted_service_descriptor.
*/
struct atsc_time_shifted_service {
EBIT2(uint16_t reserved : 6; ,
uint16_t time_shift :10; );
EBIT3(uint32_t reserved2 : 4; ,
uint32_t major_channel_number :10; ,
uint32_t minor_channel_number :10; );
} __ucsi_packed;
/**
* Process an atsc_time_shifted_service_descriptor.
*
* @param d Generic descriptor pointer.
* @return atsc_time_shifted_service_descriptor pointer, or NULL on error.
*/
static inline struct atsc_time_shifted_service_descriptor*
atsc_time_shifted_service_descriptor_codec(struct descriptor* d)
{
struct atsc_time_shifted_service_descriptor *ret =
(struct atsc_time_shifted_service_descriptor *) d;
uint8_t *buf = (uint8_t*) d + 2;
int pos = 0;
int idx;
if (d->len < 1)
return NULL;
pos++;
for(idx = 0; idx < ret->number_of_services; idx++) {
if (d->len < (pos + sizeof(struct atsc_time_shifted_service)))
return NULL;
bswap16(buf+pos);
bswap24(buf+pos+2);
pos += sizeof(struct atsc_time_shifted_service);
}
return (struct atsc_time_shifted_service_descriptor*) d;
}
/**
* Iterator for services field of a atsc_time_shifted_service_descriptor.
*
* @param d atsc_time_shifted_service_descriptor pointer.
* @param pos Variable holding a pointer to the current atsc_service_location_element.
* @param idx Integer used to count which service we are in.
*/
#define atsc_time_shifted_service_descriptor_services_for_each(d, pos, idx) \
for ((pos) = atsc_time_shifted_service_descriptor_services_first(d), idx=0; \
(pos); \
(pos) = atsc_time_shifted_service_descriptor_services_next(d, pos, ++idx))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_time_shifted_service*
atsc_time_shifted_service_descriptor_services_first(struct atsc_time_shifted_service_descriptor *d)
{
if (d->number_of_services == 0)
return NULL;
return (struct atsc_time_shifted_service *)
((uint8_t*) d + sizeof(struct atsc_time_shifted_service_descriptor));
}
static inline struct atsc_time_shifted_service*
atsc_time_shifted_service_descriptor_services_next(struct atsc_time_shifted_service_descriptor *d,
struct atsc_time_shifted_service *pos,
int idx)
{
uint8_t *next = (uint8_t *) pos + sizeof(struct atsc_time_shifted_service);
if (idx >= d->number_of_services)
return NULL;
return (struct atsc_time_shifted_service *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,81 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <libucsi/atsc/tvct_section.h>
struct atsc_tvct_section *atsc_tvct_section_codec(struct atsc_section_psip *psip)
{
uint8_t * buf = (uint8_t *) psip;
size_t pos = sizeof(struct atsc_section_psip);
size_t len = section_ext_length(&(psip->ext_head));
int idx;
struct atsc_tvct_section *tvct = (struct atsc_tvct_section *) psip;
if (len < sizeof(struct atsc_tvct_section))
return NULL;
pos++;
for(idx =0; idx < tvct->num_channels_in_section; idx++) {
if ((pos + sizeof(struct atsc_tvct_channel)) > len)
return NULL;
struct atsc_tvct_channel *channel = (struct atsc_tvct_channel *) (buf+pos);
pos += 7*2;
bswap32(buf+pos);
bswap32(buf+pos+4);
bswap16(buf+pos+8);
bswap16(buf+pos+10);
bswap16(buf+pos+12);
bswap16(buf+pos+14);
bswap16(buf+pos+16);
pos+=18;
if ((pos + channel->descriptors_length) > len)
return NULL;
if (verify_descriptors(buf + pos, channel->descriptors_length))
return NULL;
pos += channel->descriptors_length;
}
if ((pos + sizeof(struct atsc_tvct_section_part2)) > len)
return NULL;
struct atsc_tvct_section_part2 *part2 = (struct atsc_tvct_section_part2 *) (buf+pos);
bswap16(buf+pos);
pos+=2;
if ((pos + part2->descriptors_length) > len)
return NULL;
if (verify_descriptors(buf + pos, part2->descriptors_length))
return NULL;
pos += part2->descriptors_length;
if (pos != len)
return NULL;
return (struct atsc_tvct_section *) psip;
}

@ -0,0 +1,227 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_TVCT_SECTION_H
#define _UCSI_ATSC_TVCT_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/atsc/section.h>
/**
* atsc_tvct_section structure.
*/
struct atsc_tvct_section {
struct atsc_section_psip head;
uint8_t num_channels_in_section;
/* struct atsc_tvct_channel channels[] */
/* struct atsc_tvct_channel_part2 part2 */
} __ucsi_packed;
struct atsc_tvct_channel {
uint16_t short_name[7]; // UTF-16 network ordered
EBIT4(uint32_t reserved : 4; ,
uint32_t major_channel_number :10; ,
uint32_t minor_channel_number :10; ,
uint32_t modulation_mode : 8; );
uint32_t carrier_frequency;
uint16_t channel_TSID;
uint16_t program_number;
EBIT7(uint16_t ETM_location : 2; ,
uint16_t access_controlled : 1; ,
uint16_t hidden : 1; ,
uint16_t reserved1 : 2; ,
uint16_t hide_guide : 1; ,
uint16_t reserved2 : 3; ,
uint16_t service_type : 6; );
uint16_t source_id;
EBIT2(uint16_t reserved3 : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
struct atsc_tvct_section_part2 {
EBIT2(uint16_t reserved : 6; ,
uint16_t descriptors_length :10; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
static inline struct atsc_tvct_channel *atsc_tvct_section_channels_first(struct atsc_tvct_section *tvct);
static inline struct atsc_tvct_channel *
atsc_tvct_section_channels_next(struct atsc_tvct_section *tvct, struct atsc_tvct_channel *pos, int idx);
/**
* Process a atsc_tvct_section.
*
* @param section Pointer to an atsc_section_psip structure.
* @return atsc_tvct_section pointer, or NULL on error.
*/
struct atsc_tvct_section *atsc_tvct_section_codec(struct atsc_section_psip *section);
/**
* Accessor for the transport_stream_id field of a TVCT.
*
* @param tvct TVCT pointer.
* @return The transport_stream_id.
*/
static inline uint16_t atsc_tvct_section_transport_stream_id(struct atsc_tvct_section *tvct)
{
return tvct->head.ext_head.table_id_ext;
}
/**
* Iterator for the channels field in an atsc_tvct_section.
*
* @param mgt atsc_tvct_section pointer.
* @param pos Variable containing a pointer to the current atsc_tvct_channel.
* @param idx Integer used to count which channel we in.
*/
#define atsc_tvct_section_channels_for_each(mgt, pos, idx) \
for ((pos) = atsc_tvct_section_channels_first(mgt), idx=0; \
(pos); \
(pos) = atsc_tvct_section_channels_next(mgt, pos, ++idx))
/**
* Iterator for the descriptors field in a atsc_tvct_channel structure.
*
* @param channel atsc_tvct_channel pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_tvct_channel_descriptors_for_each(channel, pos) \
for ((pos) = atsc_tvct_channel_descriptors_first(channel); \
(pos); \
(pos) = atsc_tvct_channel_descriptors_next(channel, pos))
/**
* Accessor for the second part of an atsc_tvct_section.
*
* @param mgt atsc_tvct_section pointer.
* @return atsc_tvct_section_part2 pointer.
*/
static inline struct atsc_tvct_section_part2 *
atsc_tvct_section_part2(struct atsc_tvct_section *mgt)
{
int pos = sizeof(struct atsc_tvct_section);
struct atsc_tvct_channel *cur_channel;
int idx;
atsc_tvct_section_channels_for_each(mgt, cur_channel, idx) {
pos += sizeof(struct atsc_tvct_channel);
pos += cur_channel->descriptors_length;
}
return (struct atsc_tvct_section_part2 *) (((uint8_t*) mgt) + pos);
}
/**
* Iterator for the descriptors field in a atsc_tvct_section structure.
*
* @param part2 atsc_tvct_section_part2 pointer.
* @param pos Variable containing a pointer to the current descriptor.
*/
#define atsc_tvct_section_part2_descriptors_for_each(part2, pos) \
for ((pos) = atsc_tvct_section_part2_descriptors_first(part2); \
(pos); \
(pos) = atsc_tvct_section_part2_descriptors_next(part2, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_tvct_channel *
atsc_tvct_section_channels_first(struct atsc_tvct_section *tvct)
{
size_t pos = sizeof(struct atsc_tvct_section);
if (tvct->num_channels_in_section == 0)
return NULL;
return (struct atsc_tvct_channel*) (((uint8_t *) tvct) + pos);
}
static inline struct atsc_tvct_channel *
atsc_tvct_section_channels_next(struct atsc_tvct_section *tvct,
struct atsc_tvct_channel *pos,
int idx)
{
if (idx >= tvct->num_channels_in_section)
return NULL;
return (struct atsc_tvct_channel *)
(((uint8_t*) pos) + sizeof(struct atsc_tvct_channel) + pos->descriptors_length);
}
static inline struct descriptor *
atsc_tvct_channel_descriptors_first(struct atsc_tvct_channel *channel)
{
size_t pos = sizeof(struct atsc_tvct_channel);
if (channel->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) channel) + pos);
}
static inline struct descriptor *
atsc_tvct_channel_descriptors_next(struct atsc_tvct_channel *channel,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) channel + sizeof(struct atsc_tvct_channel),
channel->descriptors_length,
pos);
}
static inline struct descriptor *
atsc_tvct_section_part2_descriptors_first(struct atsc_tvct_section_part2 *part2)
{
size_t pos = sizeof(struct atsc_tvct_section_part2);
if (part2->descriptors_length == 0)
return NULL;
return (struct descriptor*) (((uint8_t *) part2) + pos);
}
static inline struct descriptor *
atsc_tvct_section_part2_descriptors_next(struct atsc_tvct_section_part2 *part2,
struct descriptor *pos)
{
return next_descriptor((uint8_t*) part2 + sizeof(struct atsc_tvct_section_part2),
part2->descriptors_length,
pos);
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,71 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <string.h>
#include "libucsi/atsc/types.h"
/* GPS epoch == unix time_t at 06/Jan/1980 */
#define GPS_EPOCH 315964800
int atsc_text_validate(uint8_t *buf, int len)
{
int i;
int j;
int number_strings;
int number_segments;
int number_bytes;
int pos = 0;
if (len == 0)
return 0;
number_strings = buf[pos];
pos++;
for(i=0; i< number_strings; i++) {
if (len < (pos+4))
return -1;
number_segments = buf[pos+3];
pos+=4;
for(j=0; j < number_segments; j++) {
if (len < (pos+3))
return -1;
number_bytes = buf[pos+2];
pos+=3;
if (len < (pos + number_bytes))
return -1;
pos += number_bytes;
}
}
return 0;
}
time_t atsctime_to_unixtime(atsctime_t atsc)
{
return atsc + GPS_EPOCH;
}
atsctime_t unixtime_to_atsctime(time_t t)
{
return t - GPS_EPOCH;
}

@ -0,0 +1,227 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_ATSC_TYPES_H
#define _UCSI_ATSC_TYPES_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <time.h>
#include <libucsi/types.h>
enum atsc_vct_modulation {
ATSC_VCT_MODULATION_ANALOG = 0x01,
ATSC_VCT_MODULATION_SCTE_MODE1 = 0x02,
ATSC_VCT_MODULATION_SCTE_MODE2 = 0x03,
ATSC_VCT_MODULATION_8VSB = 0x04,
ATSC_VCT_MODULATION_16VSB = 0x05,
};
enum atsc_vct_service_type {
ATSC_VCT_SERVICE_TYPE_ANALOG = 0x01,
ATSC_VCT_SERVICE_TYPE_TV = 0x02,
ATSC_VCT_SERVICE_TYPE_AUDIO = 0x03,
ATSC_VCT_SERVICE_TYPE_DATA = 0x04,
};
enum atsc_etm_location {
ATSC_VCT_ETM_NONE = 0x00,
ATSC_VCT_ETM_IN_THIS_PTC = 0x01,
ATSC_VCT_ETM_IN_CHANNEL_TSID = 0x02,
};
enum atsc_text_compress_type {
ATSC_TEXT_COMPRESS_NONE = 0x00,
ATSC_TEXT_COMPRESS_PROGRAM_TITLE = 0x01,
ATSC_TEXT_COMPRESS_PROGRAM_DESCRIPTION = 0x02,
};
enum atsc_text_segment_mode {
ATSC_TEXT_SEGMENT_MODE_UNICODE_RANGE_MIN = 0x00,
ATSC_TEXT_SEGMENT_MODE_UNICODE_RANGE_MAX = 0x33,
ATSC_TEXT_SEGMENT_MODE_SCSU = 0x3e,
ATSC_TEXT_SEGMENT_MODE_UTF16 = 0x3f,
ATSC_TEXT_SEGMENT_MODE_TAIWAN_BITMAP = 0x40,
ATSC_TEXT_SEGMENT_MODE_TAIWAN_CODEWORD_BITMAP = 0x41,
};
typedef uint32_t atsctime_t;
struct atsc_text {
uint8_t number_strings;
/* struct atsc_text_string strings[] */
};
struct atsc_text_string {
iso639lang_t language_code;
uint8_t number_segments;
/* struct atsc_text_string_segment segments[] */
};
struct atsc_text_string_segment {
uint8_t compression_type;
uint8_t mode;
uint8_t number_bytes;
/* uint8_t bytes[] */
};
/**
* Iterator for strings field of an atsc_text structure.
*
* @param txt atsc_text pointer.
* @param pos Variable holding a pointer to the current atsc_text_string.
* @param idx Iterator variable.
*/
#define atsc_text_strings_for_each(txt, pos, idx) \
for ((pos) = atsc_text_strings_first(txt), idx=0; \
(pos); \
(pos) = atsc_text_strings_next(txt, pos, ++idx))
/**
* Iterator for segments field of an atsc_text_string structure.
*
* @param str atsc_text_string pointer.
* @param pos Variable holding a pointer to the current atsc_text_string_segment.
* @param idx Iterator variable.
*/
#define atsc_text_string_segments_for_each(str, pos, idx) \
for ((pos) = atsc_text_string_segments_first(str), idx=0; \
(pos); \
(pos) = atsc_text_string_segments_next(str, pos, ++idx))
/**
* Accessor for the bytes field of an atsc_text_string_segment.
*
* @param seg atsc_text_string_segment pointer.
* @return Pointer to the bytes.
*/
static inline uint8_t*
atsc_text_string_segment_bytes(struct atsc_text_string_segment *d)
{
return ((uint8_t*) d) + sizeof(struct atsc_text_string_segment);
}
/**
* Validate a buffer containing an atsc_text structure.
*
* @param buf Start of the atsc_text structure.
* @param len Length in bytes of the buffer.
* @return 0 if valid, nonzero if not.
*/
extern int atsc_text_validate(uint8_t *buf, int len);
/**
* Decodes an atsc_text_segment with mode < 0x3e. Decompression of the ATSC text encoding IS
* supported. The output text will be in the UTF-8 encoding.
*
* @param segment Pointer to the segment to decode.
* @param destbuf Pointer to the malloc()ed buffer to append text to (pass NULL if none).
* @param destbufsize Size of destbuf in bytes.
* @param destbufpos Position within destbuf. This will be updated to point after the end of the
* string on exit.
* @return New value of destbufpos, or < 0 on error.
*/
extern int atsc_text_segment_decode(struct atsc_text_string_segment *segment,
uint8_t **destbuf, size_t *destbufsize, size_t *destbufpos);
/**
* Convert from ATSC time to unix time_t.
*
* @param atsc ATSC time.
* @return The time value.
*/
extern time_t atsctime_to_unixtime(atsctime_t atsc);
/**
* Convert from unix time_t to atsc time.
*
* @param t unix time_t.
* @return The atsc time value.
*/
extern atsctime_t unixtime_to_atsctime(time_t t);
/******************************** PRIVATE CODE ********************************/
static inline struct atsc_text_string*
atsc_text_strings_first(struct atsc_text *txt)
{
if (txt->number_strings == 0)
return NULL;
return (struct atsc_text_string *)
((uint8_t*) txt + sizeof(struct atsc_text));
}
static inline struct atsc_text_string*
atsc_text_strings_next(struct atsc_text *txt, struct atsc_text_string *pos, int idx)
{
int i;
uint8_t *buf;
if (idx >= txt->number_strings)
return NULL;
buf = ((uint8_t*) pos) + sizeof(struct atsc_text_string);
for(i=0; i < pos->number_segments; i++) {
struct atsc_text_string_segment *seg =
(struct atsc_text_string_segment *) buf;
buf += sizeof(struct atsc_text_string_segment);
buf += seg->number_bytes;
}
return (struct atsc_text_string *) buf;
}
static inline struct atsc_text_string_segment*
atsc_text_string_segments_first(struct atsc_text_string *str)
{
if (str->number_segments == 0)
return NULL;
return (struct atsc_text_string_segment *)
((uint8_t*) str + sizeof(struct atsc_text_string));
}
static inline struct atsc_text_string_segment*
atsc_text_string_segments_next(struct atsc_text_string *str,
struct atsc_text_string_segment *pos, int idx)
{
if (idx >= str->number_segments)
return NULL;
return (struct atsc_text_string_segment *)
(((uint8_t*) pos) + sizeof(struct atsc_text_string_segment) + pos->number_bytes);
}
#ifdef __cplusplus
}
#endif
#endif

@ -40,9 +40,9 @@ extern uint32_t crc32tbl[];
* @param len Number of bytes.
* @return Calculated CRC.
*/
static inline uint32_t crc32(uint32_t crc, uint8_t* buf, int len)
static inline uint32_t crc32(uint32_t crc, uint8_t* buf, size_t len)
{
int i;
size_t i;
for (i=0; i< len; i++) {
crc = (crc << 8) ^ crc32tbl[((crc >> 24) ^ buf[i]) & 0xff];

@ -47,7 +47,7 @@ struct descriptor {
* @return Pointer to next descriptor, or NULL if there are none.
*/
static inline struct descriptor *
next_descriptor(uint8_t * buf, int len, struct descriptor * pos)
next_descriptor(uint8_t * buf, size_t len, struct descriptor * pos)
{
uint8_t* next;
@ -105,9 +105,9 @@ static inline int
/******************************** PRIVATE CODE ********************************/
static inline int verify_descriptors(uint8_t * buf, int len)
static inline int verify_descriptors(uint8_t * buf, size_t len)
{
int pos = 0;
size_t pos = 0;
while (pos < len) {
if ((pos + 2) > len)

@ -40,7 +40,7 @@ struct dvb_ac3_descriptor {
uint8_t bsid_flag : 1; ,
uint8_t mainid_flag : 1; ,
uint8_t asvc_flag : 1; ,
uint8_t reserved : 4; )
uint8_t reserved : 4; );
/* uint8_t additional_info[] */
} __ucsi_packed;

@ -37,7 +37,7 @@ struct dvb_adaptation_field_data_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 7; ,
uint8_t announcement_switching_data : 1; )
uint8_t announcement_switching_data : 1; );
} __ucsi_packed;
/**

@ -36,7 +36,7 @@ extern "C"
enum {
AVB_AIT_APPLICATION_VISIBILITY_HIDDEN = 0x00,
AVB_AIT_APPLICATION_VISIBILITY_APPSONLY = 0x01,
AVB_AIT_APPLICATION_VISIBILITY_VISIBLE = 0x03
AVB_AIT_APPLICATION_VISIBILITY_VISIBLE = 0x03,
};
/**
@ -66,7 +66,7 @@ struct dvb_ait_application_profile {
struct dvb_ait_application_descriptor_part2 {
EBIT3(uint8_t service_bound_flag : 1; ,
uint8_t visibility : 2; ,
uint8_t reserved : 5; )
uint8_t reserved : 5; );
uint8_t application_priority;
/* uint8_t transport_protocol_label[] */
} __ucsi_packed;

@ -45,7 +45,7 @@ enum {
AIT_APPLICATION_ICON_FLAG_128_128 = 0x040,
AIT_APPLICATION_ICON_FLAG_128_128_43 = 0x080,
AIT_APPLICATION_ICON_FLAG_96_128_169 = 0x100
AIT_APPLICATION_ICON_FLAG_96_128_169 = 0x100,
};
/**

@ -42,7 +42,7 @@ struct dvb_ancillary_data_descriptor {
uint8_t dab_ancillary_data : 1; ,
uint8_t announcement_switching_data : 1; ,
uint8_t extended_ancillary_data : 1; ,
uint8_t dvd_video_ancillary_data : 1; )
uint8_t dvd_video_ancillary_data : 1; );
} __ucsi_packed;
/**

@ -41,7 +41,7 @@ enum {
DVB_ANNOUNCEMENT_SUPPORT_NEWS_FLASH = 0x10,
DVB_ANNOUNCEMENT_SUPPORT_WEATHER_FLASH = 0x20,
DVB_ANNOUNCEMENT_SUPPORT_EVENT_ANNOUNCEMENT = 0x40,
DVB_ANNOUNCEMENT_SUPPORT_PERSONAL_CALL = 0x80
DVB_ANNOUNCEMENT_SUPPORT_PERSONAL_CALL = 0x80,
};
/**
@ -55,7 +55,7 @@ enum {
DVB_ANNOUNCEMENT_TYPE_NEWS_FLASH = 0x04,
DVB_ANNOUNCEMENT_TYPE_WEATHER_FLASH = 0x05,
DVB_ANNOUNCEMENT_TYPE_EVENT_ANNOUNCEMENT = 0x06,
DVB_ANNOUNCEMENT_TYPE_PERSONAL_CALL = 0x07
DVB_ANNOUNCEMENT_TYPE_PERSONAL_CALL = 0x07,
};
/**
@ -65,7 +65,7 @@ enum {
DVB_REFERENCE_TYPE_AUDIO = 0x00,
DVB_REFERENCE_TYPE_OTHER_AUDIO = 0x01,
DVB_REFERENCE_TYPE_OTHER_SERVICE = 0x02,
DVB_REFERENCE_TYPE_OTHER_TS = 0x03
DVB_REFERENCE_TYPE_OTHER_TS = 0x03,
};
/**
@ -83,7 +83,7 @@ struct dvb_announcement_support_descriptor {
struct dvb_announcement_support_entry {
EBIT3(uint8_t announcement_type : 4; ,
uint8_t reserved : 1; ,
uint8_t reference_type : 3; )
uint8_t reference_type : 3; );
/* Only if reference_type == 1, 2 or 3:
* struct dvb_announcement_support_reference reference */
} __ucsi_packed;

@ -45,7 +45,7 @@ struct dvb_application_signalling_descriptor {
struct dvb_application_signalling_entry {
uint16_t application_type;
EBIT2(uint8_t reserved : 3; ,
uint8_t AIT_version_number : 5; )
uint8_t AIT_version_number : 5; );
} __ucsi_packed;
/**
@ -105,8 +105,8 @@ static inline struct dvb_application_signalling_entry*
}
static inline struct dvb_application_signalling_entry*
dvb_application_signalling_descriptor_countries_next(struct dvb_application_signalling_descriptor *d,
struct dvb_application_signalling_entry *pos)
dvb_application_signalling_descriptor_entries_next(struct dvb_application_signalling_descriptor *d,
struct dvb_application_signalling_entry *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_application_signalling_entry);

@ -24,8 +24,8 @@
struct dvb_bat_section * dvb_bat_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
struct dvb_bat_section * ret = (struct dvb_bat_section *) ext;
if (len < sizeof(struct dvb_bat_section))

@ -71,7 +71,7 @@ struct dvb_bat_section *dvb_bat_section_codec(struct section_ext *section);
/**
* Accessor for the bouquet_id field of a BAT.
*
*
* @param bat BAT pointer.
* @return The bouquet_id.
*/

@ -38,10 +38,10 @@ struct dvb_cable_delivery_descriptor {
uint32_t frequency; // BCD, units 100Hz
EBIT2(uint16_t reserved : 12; ,
uint16_t fec_outer : 4; )
uint16_t fec_outer : 4; );
uint8_t modulation;
EBIT2(uint32_t symbol_rate : 28; , // BCD, units 100Hz
uint32_t fec_inner : 4; )
uint32_t fec_inner : 4; );
} __ucsi_packed;
/**

@ -160,7 +160,7 @@ static inline struct dvb_cell_frequency_link_cell*
}
static inline struct dvb_cell_frequency_link_cell_subcell*
dvb_cell_frequency_cell_subcells_first(struct dvb_cell_frequency_link_cell *d)
dvb_cell_frequency_link_cell_subcells_first(struct dvb_cell_frequency_link_cell *d)
{
if (d->subcell_loop_info_length == 0)
return NULL;
@ -170,7 +170,7 @@ static inline struct dvb_cell_frequency_link_cell_subcell*
}
static inline struct dvb_cell_frequency_link_cell_subcell*
dvb_cell_frequency_cell_subcells_next(struct dvb_cell_frequency_link_cell *cell,
dvb_cell_frequency_link_cell_subcells_next(struct dvb_cell_frequency_link_cell *cell,
struct dvb_cell_frequency_link_cell_subcell *pos)
{
uint8_t *end = (uint8_t*) cell + cell->subcell_loop_info_length;

@ -48,7 +48,7 @@ struct dvb_cell_list_entry {
uint16_t cell_longitude;
EBIT3(uint32_t cell_extend_of_latitude :12; ,
uint32_t cell_extend_of_longitude :12; ,
uint32_t subcell_info_loop_length : 8; )
uint32_t subcell_info_loop_length : 8; );
/* struct dvb_subcell_list_entry subcells[] */
} __ucsi_packed;
@ -60,7 +60,7 @@ struct dvb_subcell_list_entry {
uint16_t subcell_latitude;
uint16_t subcell_longitude;
EBIT2(uint32_t subcell_extend_of_latitude :12; ,
uint32_t subcell_extend_of_longitude :12; )
uint32_t subcell_extend_of_longitude :12; );
} __ucsi_packed;
/**

@ -38,7 +38,7 @@ enum {
DVB_STREAM_CONTENT_VIDEO = 0x01,
DVB_STREAM_CONTENT_AUDIO = 0x02,
DVB_STREAM_CONTENT_SUBTITLE = 0x03,
DVB_STREAM_CONTENT_AC3 = 0x04
DVB_STREAM_CONTENT_AC3 = 0x04,
};
/**
@ -84,7 +84,7 @@ enum {
DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR = 0x20,
DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_43 = 0x21,
DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_169 = 0x22,
DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_2211 = 0x23
DVB_COMPONENT_TYPE_SUBTITLE_DVB_HARDHEAR_2211 = 0x23,
};
/**
@ -94,7 +94,7 @@ struct dvb_component_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 4; ,
uint8_t stream_content : 4; )
uint8_t stream_content : 4; );
uint8_t component_type;
uint8_t component_tag;
iso639lang_t language_code;

@ -46,9 +46,9 @@ struct dvb_content_descriptor {
*/
struct dvb_content_nibble {
EBIT2(uint8_t content_nibble_level_1 : 4; ,
uint8_t content_nibble_level_2 : 4; )
uint8_t content_nibble_level_2 : 4; );
EBIT2(uint8_t user_nibble_1 : 4; ,
uint8_t user_nibble_2 : 4; )
uint8_t user_nibble_2 : 4; );
} __ucsi_packed;
/**

@ -39,7 +39,7 @@ enum {
DVB_CRID_TYPE_NONE = 0x00,
DVB_CRID_TYPE_ITEM = 0x01,
DVB_CRID_TYPE_SERIES = 0x02,
DVB_CRID_TYPE_RECOMMENDATION = 0x03
DVB_CRID_TYPE_RECOMMENDATION = 0x03,
};
/**
@ -47,7 +47,7 @@ enum {
*/
enum {
DVB_CRID_LOCATION_THIS_DESCRIPTOR = 0x00,
DVB_CRID_LOCATION_CIT = 0x01
DVB_CRID_LOCATION_CIT = 0x01,
};
/**
@ -64,7 +64,7 @@ struct dvb_content_identifier_descriptor {
*/
struct dvb_content_identifier_entry {
EBIT2(uint8_t crid_type : 6; ,
uint8_t crid_location : 2; )
uint8_t crid_location : 2; );
/* struct dvb_content_identifier_data_00 data0 */
/* struct dvb_content_identifier_data_01 data1 */
} __ucsi_packed;
@ -154,6 +154,17 @@ static inline struct dvb_content_identifier_entry_data_0*
return (struct dvb_content_identifier_entry_data_0*)
((uint8_t*) d + sizeof(struct dvb_content_identifier_entry));
}
/**
* Accessor for the data field of a dvb_content_identifier_entry_data_0.
*
* @param d dvb_content_identifier_entry_data_0 pointer.
* @return Pointer, or NULL on error.
*/
static inline uint8_t*
dvb_content_identifier_entry_data_0_data(struct dvb_content_identifier_entry_data_0 *d)
{
return ((uint8_t*) d + sizeof(struct dvb_content_identifier_entry_data_0));
}
/**
* Accessor for the data1 field of a dvb_content_identifier_entry.

@ -38,7 +38,7 @@ struct dvb_country_availability_descriptor {
struct descriptor d;
EBIT2(uint8_t country_availability_flag : 1; ,
uint8_t reserved : 7; )
uint8_t reserved : 7; );
/* struct dvb_country_availability_entry countries[] */
} __ucsi_packed;

@ -30,6 +30,23 @@ extern "C"
#include <libucsi/descriptor.h>
#include <libucsi/endianops.h>
/**
* Possible values for data_broadcast_id.
*/
enum {
DVB_BROADCAST_ID_DATA_PIPE = 0X0001,
DVB_BROADCAST_ID_ASYNCHRONOUS_DATA_STREAM = 0X0002,
DVB_BROADCAST_ID_SYNCHRONOUS_DATA_STREAM = 0X0003,
DVB_BROADCAST_ID_SYNCHRONISED_DATA_STREAM = 0X0004,
DVB_BROADCAST_ID_MULTI_PROTOCOL_ENCAPSULATION = 0X0005,
DVB_BROADCAST_ID_DATA_CAROUSEL = 0X0006,
DVB_BROADCAST_ID_OBJECT_CAROUSEL = 0X0007,
DVB_BROADCAST_ID_DVB_ATM_STREAMS = 0X0008,
DVB_BROADCAST_ID_HIGHER_PROTOCOLS = 0X0009,
DVB_BROADCAST_ID_SOFTWARE_UPDATE = 0x000A,
DVB_BROADCAST_ID_IP_MAC_NOTIFICATION_TABLE = 0x000B,
};
/**
* dvb_data_broadcast_id_descriptor structure.
*/
@ -40,6 +57,26 @@ struct dvb_data_broadcast_id_descriptor {
/* uint8_t id_selector_byte[] */
} __ucsi_packed;
/**
* id_selector_byte for 0x000b data_broadcast_id (IP/MAC Notification Table).
*/
struct dvb_id_selector_byte_000b {
uint8_t platform_id_data_length;
/* struct dvb_ip_mac_notification_info infos[] */
/* uint8_t private_data[] */
} __ucsi_packed;
/**
* Entries in the infos field of a dvb_id_selector_byte_0b.
*/
struct dvb_ip_mac_notification_info {
EBIT2(uint32_t platform_id : 24; ,
uint8_t action_type : 8; );
EBIT3(uint8_t reserved : 2; ,
uint8_t INT_versioning_flag : 1; ,
uint8_t INT_version : 5; );
} __ucsi_packed;
/**
* Process a dvb_data_broadcast_id_descriptor.
*
@ -81,6 +118,100 @@ static inline int
return d->d.len - 2;
}
/**
* Accessor for a dvb_id_selector_byte_000b pointer.
*
* @param d dvb_data_broadcast_id_descriptor pointer.
* @return Pointer to the data field.
*/
static inline struct dvb_id_selector_byte_000b *
dvb_id_selector_byte_000b(struct dvb_data_broadcast_id_descriptor *d)
{
if (d->data_broadcast_id != DVB_BROADCAST_ID_IP_MAC_NOTIFICATION_TABLE)
return NULL;
return (struct dvb_id_selector_byte_000b *) dvb_data_broadcast_id_descriptor_id_selector_byte(d);
}
/**
* Iterator for the dvb_ip_mac_notification_info field of a dvb_id_selector_byte_000b.
*
* @param id_selector_byte dvb_id_selector_byte_000b pointer.
* @param pos Variable containing a pointer to the current dvb_ip_mac_notification_info.
*/
#define dvb_id_selector_byte_000b_ip_mac_notification_info_for_each(id_selector_byte, pos) \
for ((pos) = dvb_ip_mac_notification_info_first(id_selector_byte); \
(pos); \
(pos) = dvb_ip_mac_notification_info_next(id_selector_byte, pos))
/**
* Length of the private_data field of a dvb_id_selector_byte_000b.
*
* @param d descriptor pointer.
* @param i dvb_id_selector_byte_000b pointer.
* @return Length of the field.
*/
static inline uint8_t
dvb_id_selector_byte_000b_private_data_length(struct descriptor *d,
struct dvb_id_selector_byte_000b *i)
{
return (uint8_t) (d->len -
sizeof(struct descriptor) -
i->platform_id_data_length -
sizeof(struct dvb_id_selector_byte_000b));
}
/**
* Accessor for the private_data field of a dvb_id_selector_byte_000b.
*
* @param d descriptor pointer.
* @param i dvb_id_selector_byte_000b pointer.
* @return Pointer to the field.
*/
static inline uint8_t *
dvb_id_selector_byte_000b_private_data(struct descriptor *d,
struct dvb_id_selector_byte_000b *i)
{
if (dvb_id_selector_byte_000b_private_data_length(d, i) <= 0)
return NULL;
return (uint8_t *) i + i->platform_id_data_length + sizeof(struct dvb_id_selector_byte_000b);
}
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ip_mac_notification_info *
dvb_ip_mac_notification_info_first(struct dvb_id_selector_byte_000b *d)
{
if (d->platform_id_data_length == 0)
return NULL;
bswap32((uint8_t *) d + sizeof(struct dvb_id_selector_byte_000b));
return (struct dvb_ip_mac_notification_info *) ((uint8_t *) d + sizeof(struct dvb_id_selector_byte_000b));
}
static inline struct dvb_ip_mac_notification_info *
dvb_ip_mac_notification_info_next(struct dvb_id_selector_byte_000b *d,
struct dvb_ip_mac_notification_info *pos)
{
uint8_t *end = (uint8_t *) d + d->platform_id_data_length;
uint8_t *next = (uint8_t *) pos +
sizeof(struct dvb_id_selector_byte_000b) +
sizeof(struct dvb_ip_mac_notification_info);
if (next >= end)
return NULL;
bswap32(next);
return (struct dvb_ip_mac_notification_info *) next;
}
#ifdef __cplusplus
}
#endif

@ -47,6 +47,9 @@ extern "C"
#include <libucsi/dvb/dsng_descriptor.h>
#include <libucsi/dvb/extended_event_descriptor.h>
#include <libucsi/dvb/frequency_list_descriptor.h>
#include <libucsi/dvb/ip_mac_platform_name_descriptor.h>
#include <libucsi/dvb/ip_mac_platform_provider_name_descriptor.h>
#include <libucsi/dvb/ip_mac_stream_location_descriptor.h>
#include <libucsi/dvb/linkage_descriptor.h>
#include <libucsi/dvb/local_time_offset_descriptor.h>
#include <libucsi/dvb/mosaic_descriptor.h>
@ -74,15 +77,28 @@ extern "C"
#include <libucsi/dvb/stream_identifier_descriptor.h>
#include <libucsi/dvb/stuffing_descriptor.h>
#include <libucsi/dvb/subtitling_descriptor.h>
#include <libucsi/dvb/target_ip_address_descriptor.h>
#include <libucsi/dvb/target_ipv6_address_descriptor.h>
#include <libucsi/dvb/target_ip_slash_descriptor.h>
#include <libucsi/dvb/target_ip_source_slash_descriptor.h>
#include <libucsi/dvb/target_ipv6_slash_descriptor.h>
#include <libucsi/dvb/target_ipv6_source_slash_descriptor.h>
#include <libucsi/dvb/telephone_descriptor.h>
#include <libucsi/dvb/teletext_descriptor.h>
#include <libucsi/dvb/terrestrial_delivery_descriptor.h>
#include <libucsi/dvb/time_shifted_event_descriptor.h>
#include <libucsi/dvb/time_shifted_service_descriptor.h>
#include <libucsi/dvb/time_slice_fec_identifier_descriptor.h>
#include <libucsi/dvb/transport_stream_descriptor.h>
#include <libucsi/dvb/tva_id_descriptor.h>
#include <libucsi/dvb/vbi_data_descriptor.h>
#include <libucsi/dvb/vbi_teletext_descriptor.h>
#include <libucsi/endianops.h>
/**
* The following are disabled because support is incomplete just now.
*/
/*
#include <libucsi/dvb/rnt_rar_over_dvb_stream_descriptor.h>
#include <libucsi/dvb/rnt_rar_over_ip_descriptor.h>
#include <libucsi/dvb/rnt_rnt_scan_descriptor.h>
@ -90,7 +106,7 @@ extern "C"
#include <libucsi/dvb/ait_application_name_descriptor.h>
#include <libucsi/dvb/ait_external_application_authorisation_descriptor.h>
#include <libucsi/dvb/ait_application_icons_descriptor.h>
#include <libucsi/endianops.h>
*/
/**
* The following are not implemented just now
@ -169,6 +185,10 @@ enum dvb_descriptor_tag {
dtag_dvb_time_slice_fec_identifier = 0x77,
dtag_dvb_ecm_repetition_rate = 0x78,
dtag_dvb_s2_satellite_delivery_descriptor= 0x79,
dtag_dvb_enhanced_ac3_descriptor = 0x7a,
dtag_dvb_dts_descriptor = 0x7b,
dtag_dvb_aac_descriptor = 0x7c,
dtag_dvb_extension_descriptor = 0x7f,
/* descriptors which may only appear in an RNT */
dtag_dvb_rnt_rar_over_dvb_stream = 0x40,
@ -188,8 +208,20 @@ enum dvb_descriptor_tag {
dtag_dvb_ait_application_icons = 0x0b,
dtag_dvb_ait_prefetch = 0x0c,
dtag_dvb_ait_dii_location = 0x0d,
dtag_dvb_ait_ip_signalling = 0x11
};/*__ucsi_packed;*/
dtag_dvb_ait_ip_signalling = 0x11,
/* descriptors which may only appear in INT */
dtag_dvb_target_ip_address = 0x09,
dtag_dvb_target_ipv6_address = 0x0a,
dtag_dvb_ip_mac_platform_name = 0x0c,
dtag_dvb_ip_mac_platform_provider_name = 0x0d,
dtag_dvb_target_ip_slash = 0x0f,
dtag_dvb_target_ip_source_slash = 0x10,
dtag_dvb_target_ipv6_slash = 0x11,
dtag_dvb_target_ipv6_source_slash = 0x12,
dtag_dvb_ip_mac_stream_location = 0x13,
};
#ifdef __cplusplus
}

@ -24,9 +24,9 @@
struct dvb_eit_section *dvb_eit_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct dvb_eit_section))
return NULL;
@ -34,14 +34,14 @@ struct dvb_eit_section *dvb_eit_section_codec(struct section_ext * ext)
pos += 2;
bswap16(buf + pos);
pos += 4;
while (pos < len) {
struct dvb_eit_event * event =
(struct dvb_eit_event *) (buf + pos);
if ((pos + sizeof(struct dvb_eit_event)) > len)
return NULL;
bswap16(buf + pos);
bswap16(buf + pos + 10);

@ -67,7 +67,7 @@ struct dvb_eit_section *dvb_eit_section_codec(struct section_ext *section);
/**
* Accessor for the service_id field of an EIT.
*
*
* @param eit EIT pointer.
* @return The service_id.
*/
@ -111,7 +111,7 @@ static inline uint16_t dvb_eit_section_service_id(struct dvb_eit_section *eit)
static inline struct dvb_eit_event *
dvb_eit_section_events_first(struct dvb_eit_section *eit)
{
int pos = sizeof(struct dvb_eit_section);
size_t pos = sizeof(struct dvb_eit_section);
if (pos >= section_ext_length(&eit->head))
return NULL;

@ -38,7 +38,7 @@ struct dvb_extended_event_descriptor {
struct descriptor d;
EBIT2(uint8_t descriptor_number : 4; ,
uint8_t last_descriptor_number : 4; )
uint8_t last_descriptor_number : 4; );
iso639lang_t language_code;
uint8_t length_of_items;
/* struct dvb_extended_event_item items[] */

@ -36,7 +36,7 @@ extern "C"
enum {
DVB_CODING_TYPE_SATELLITE = 0x01,
DVB_CODING_TYPE_CABLE = 0x02,
DVB_CODING_TYPE_TERRESTRIAL = 0x03
DVB_CODING_TYPE_TERRESTRIAL = 0x03,
};
/**
@ -46,7 +46,7 @@ struct dvb_frequency_list_descriptor {
struct descriptor d;
EBIT2(uint8_t reserved : 6; ,
uint8_t coding_type : 2; )
uint8_t coding_type : 2; );
/* uint32_t centre_frequencies [] */
} __ucsi_packed;

@ -26,16 +26,15 @@ struct dvb_int_section * dvb_int_section_codec(struct section_ext *ext)
{
uint8_t *buf = (uint8_t *) ext;
struct dvb_int_section *in = (struct dvb_int_section *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct dvb_int_section))
return NULL;
bswap32(buf+8);
bswap16(buf+12);
pos += 9;
pos += 6;
if (len - pos < in->platform_descriptors_length)
return NULL;

@ -72,7 +72,7 @@ extern struct dvb_int_section * dvb_int_section_codec(struct section_ext *sectio
/**
* Accessor for the action_type field of an INT.
*
*
* @param intp INT pointer.
* @return The action_type.
*/
@ -83,7 +83,7 @@ static inline uint8_t dvb_int_section_action_type(struct dvb_int_section *intp)
/**
* Accessor for the platform_id_hash field of an INT.
*
*
* @param intp INT pointer.
* @return The platform_id_hash.
*/

@ -0,0 +1,87 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR
#define _UCSI_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_ip_platform_name_descriptor structure.
*/
struct dvb_ip_platform_name_descriptor {
struct descriptor d;
iso639lang_t language_code;
/* uint8_t text[] */
} __ucsi_packed;
/**
* Process a dvb_ip_platform_name_descriptor.
*
* @param d Pointer to a generic descriptor.
* @return dvb_ip_platform_name_descriptor pointer, or NULL on error.
*/
static inline struct dvb_ip_platform_name_descriptor*
dvb_ip_platform_name_descriptor_codec(struct descriptor* d)
{
if (d->len < (sizeof(struct dvb_ip_platform_name_descriptor) - 2))
return NULL;
return (struct dvb_ip_platform_name_descriptor*) d;
}
/**
* Accessor for the text field of a dvb_ip_platform_name_descriptor.
*
* @param d dvb_ip_platform_name_descriptor pointer.
* @return Pointer to the field.
*/
static inline uint8_t *
dvb_ip_platform_name_descriptor_text(struct dvb_ip_platform_name_descriptor *d)
{
return (uint8_t *) d + sizeof(struct dvb_ip_platform_name_descriptor);
}
/**
* Determine the length of the text field of a dvb_ip_platform_name_descriptor.
*
* @param d dvb_ip_platform_name_descriptor pointer.
* @return Length of the field in bytes.
*/
static inline int
dvb_ip_platform_name_descriptor_text_length(struct dvb_ip_platform_name_descriptor *d)
{
return d->d.len - 3;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,87 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR
#define _UCSI_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_ip_platform_provider_name_descriptor structure.
*/
struct dvb_ip_platform_provider_name_descriptor {
struct descriptor d;
iso639lang_t language_code;
/* uint8_t text[] */
} __ucsi_packed;
/**
* Process a dvb_ip_platform_provider_name_descriptor.
*
* @param d Pointer to a generic descriptor.
* @return dvb_ip_platform_provider_name_descriptor pointer, or NULL on error.
*/
static inline struct dvb_ip_platform_provider_name_descriptor*
dvb_ip_platform_provider_name_descriptor_codec(struct descriptor* d)
{
if (d->len < (sizeof(struct dvb_ip_platform_provider_name_descriptor) - 2))
return NULL;
return (struct dvb_ip_platform_provider_name_descriptor*) d;
}
/**
* Accessor for the text field of a dvb_ip_platform_provider_name_descriptor.
*
* @param d dvb_ip_platform_provider_name_descriptor pointer.
* @return Pointer to the field.
*/
static inline uint8_t *
dvb_ip_platform_provider_name_descriptor_text(struct dvb_ip_platform_provider_name_descriptor *d)
{
return (uint8_t *) d + sizeof(struct dvb_ip_platform_provider_name_descriptor);
}
/**
* Determine the length of the text field of a dvb_ip_platform_provider_name_descriptor.
*
* @param d dvb_ip_platform_provider_name_descriptor pointer.
* @return Length of the field in bytes.
*/
static inline int
dvb_ip_platform_provider_name_descriptor_text_length(struct dvb_ip_platform_provider_name_descriptor *d)
{
return d->d.len - 3;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,73 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_IP_MAC_STREAM_LOCATION_DESCRIPTOR
#define _UCSI_DVB_IP_MAC_PLATFORM_PROVIDER_NAME_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_ip_mac_stream_location_descriptor structure.
*/
struct dvb_ip_mac_stream_location_descriptor {
struct descriptor d;
uint16_t network_id;
uint16_t original_network_id;
uint16_t transport_stream_id;
uint16_t service_id;
uint8_t component_tag;
} __ucsi_packed;
/**
* Process a dvb_ip_mac_stream_location_descriptor.
*
* @param d Generic descriptor pointer.
* @return dvb_ip_mac_stream_location_descriptor pointer, or NULL on error.
*/
static inline struct dvb_ip_mac_stream_location_descriptor*
dvb_ip_mac_stream_location_descriptor_codec(struct descriptor* d)
{
uint8_t* buf = (uint8_t*) d + 2;
if (d->len != (sizeof(struct dvb_ip_mac_stream_location_descriptor) - 2))
return NULL;
bswap16(buf);
bswap16(buf+2);
bswap16(buf+4);
bswap16(buf+6);
return (struct dvb_ip_mac_stream_location_descriptor*) d;
}
#ifdef __cplusplus
}
#endif
#endif

@ -46,7 +46,7 @@ enum {
DVB_LINKAGE_TYPE_SOFTWARE_UPDATE = 0x09,
DVB_LINKAGE_TYPE_TS_WITH_SSU_BAT_NIT = 0x0a,
DVB_LINKAGE_TYPE_IP_MAC_NOTIFICATION = 0x0b,
DVB_LINKAGE_TYPE_TS_WITH_INT_BAT_NIT = 0x0c
DVB_LINKAGE_TYPE_TS_WITH_INT_BAT_NIT = 0x0c,
};
/**
@ -55,7 +55,7 @@ enum {
enum {
DVB_HAND_OVER_TYPE_IDENTICAL_NEIGHBOURING_COUNTRY = 0x01,
DVB_HAND_OVER_TYPE_LOCAL_VARIATION = 0x02,
DVB_HAND_OVER_TYPE_ASSOCIATED_SERVICE = 0x03
DVB_HAND_OVER_TYPE_ASSOCIATED_SERVICE = 0x03,
};
/**
@ -63,7 +63,7 @@ enum {
*/
enum {
DVB_ORIGIN_TYPE_NIT = 0x00,
DVB_ORIGIN_TYPE_SDT = 0x01
DVB_ORIGIN_TYPE_SDT = 0x01,
};
/**
@ -85,7 +85,7 @@ struct dvb_linkage_descriptor {
struct dvb_linkage_data_08 {
EBIT3(uint8_t hand_over_type : 4; ,
uint8_t reserved : 3; ,
uint8_t origin_type : 1; )
uint8_t origin_type : 1; );
/* uint16_t network_id if hand_over_type == 1,2,3 */
/* uint16_t initial_service_id if origin_type = 0 */
/* uint8_t data[] */
@ -104,7 +104,7 @@ struct dvb_linkage_data_0b {
*/
struct dvb_platform_id {
EBIT2(uint32_t platform_id : 24; ,
uint32_t platform_name_loop_length : 8; )
uint8_t platform_name_loop_length : 8; );
/* struct platform_name names[] */
} __ucsi_packed;
@ -187,6 +187,8 @@ static inline struct dvb_linkage_descriptor*
return NULL;
while (pos2 < l_0b->platform_id_data_length) {
bswap32(buf + pos + pos2);
struct dvb_platform_id *p_id = (struct dvb_platform_id *) (buf + pos + pos2);
if ((len - pos - pos2) < p_id->platform_name_loop_length)
return NULL;
@ -359,7 +361,7 @@ static inline struct dvb_linkage_data_0b *
* @param linkage dvb_linkage_data_0b pointer.
* @param pos Variable containing a pointer to the current dvb_platform_id.
*/
#define dvb_dvb_linkage_data_0b_platform_id_for_each(linkage, pos) \
#define dvb_linkage_data_0b_platform_id_for_each(linkage, pos) \
for ((pos) = dvb_platform_id_first(linkage); \
(pos); \
(pos) = dvb_platform_id_next(linkage, pos))

@ -48,7 +48,7 @@ struct dvb_local_time_offset {
iso639country_t country_code;
EBIT3(uint8_t country_region_id : 6; ,
uint8_t reserved : 1; ,
uint8_t local_time_offset_polarity : 1; )
uint8_t local_time_offset_polarity : 1; );
dvbhhmm_t local_time_offset;
dvbdate_t time_of_change;
dvbhhmm_t next_time_offset;

@ -36,7 +36,7 @@ extern "C"
*/
enum {
DVB_BROADCAST_ID_MHP_OBJECT_CAROUSEL = 0x00f0,
DVB_BROADCAST_ID_MHP_MPE = 0x00f1
DVB_BROADCAST_ID_MHP_MPE = 0x00f1,
};
/**

@ -39,7 +39,7 @@ struct dvb_mosaic_descriptor {
EBIT4(uint8_t mosaic_entry_point : 1; ,
uint8_t number_of_horiz_elementary_cells: 3; ,
uint8_t reserved : 1; ,
uint8_t number_of_vert_elementary_cells : 3; )
uint8_t number_of_vert_elementary_cells : 3; );
/* struct dvb_mosaic_info infos[] */
} __ucsi_packed;
@ -49,7 +49,7 @@ struct dvb_mosaic_descriptor {
struct dvb_mosaic_info {
EBIT3(uint16_t logical_cell_id : 6; ,
uint16_t reserved : 7; ,
uint16_t logical_cell_presentation_info : 3; )
uint16_t logical_cell_presentation_info : 3; );
uint8_t elementary_cell_field_length;
/* struct dvb_mosaic_elementary_cell_field fields[] */
/* struct dvb_mosaic_info_part2 part2 */
@ -61,7 +61,7 @@ struct dvb_mosaic_info {
*/
struct dvb_mosaic_elementary_cell_field {
EBIT2(uint8_t reserved : 2; ,
uint8_t elementary_cell_id : 6; )
uint8_t elementary_cell_id : 6; );
} __ucsi_packed;
/**

@ -0,0 +1,73 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2008 Patrick Boettcher (pb@linuxtv.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_MPE_FEC_SECTION_H
#define _UCSI_DVB_MPE_FEC_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/mpeg/section.h>
/**
* mpe_fec_section structure. TODO
*/
struct mpe_fec_section {
struct section head;
};
/**
* real_time_paramters
* can also be found in datagram_section in MAC4-1-bytes */
struct real_time_parameters {
EBIT4(uint32_t delta_t : 12; ,
uint32_t table_boundary : 1; ,
uint32_t frame_boundary : 1; ,
uint32_t address : 18; )
};
static inline struct real_time_parameters * datagram_section_real_time_parameters_codec(struct datagram_section *d)
{
struct real_time_parameters *rt = (struct real_time_parameters *) &d->MAC_address_4;
uint8_t b[4];
b[0] = d->MAC_address_4;
b[1] = d->MAC_address_3;
b[2] = d->MAC_address_2;
b[3] = d->MAC_address_1;
rt->delta_t = (b[0] << 4) | ((b[1] >> 4) & 0x0f);
rt->table_boundary = (b[1] >> 3) & 0x1;
rt->frame_boundary = (b[1] >> 2) & 0x1;
rt->address = ((b[1] & 0x3) << 16) | (b[2] << 8) | b[3];
return rt;
}
#ifdef __cplusplus
}
#endif
#endif

@ -25,8 +25,8 @@ struct dvb_nit_section *dvb_nit_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *) ext;
struct dvb_nit_section * ret = (struct dvb_nit_section *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct dvb_nit_section))
return NULL;
@ -76,4 +76,3 @@ struct dvb_nit_section *dvb_nit_section_codec(struct section_ext * ext)
return ret;
}

@ -49,7 +49,7 @@ enum {
DVB_PARENTAL_RATING_MIN_14YEARS = 0x0c,
DVB_PARENTAL_RATING_MIN_15YEARS = 0x0d,
DVB_PARENTAL_RATING_MIN_16YEARS = 0x0e,
DVB_PARENTAL_RATING_MIN_17YEARS = 0x0f
DVB_PARENTAL_RATING_MIN_17YEARS = 0x0f,
};
/**

@ -41,7 +41,7 @@ struct dvb_partial_transport_stream_descriptor {
uint64_t reserved_2 : 2; ,
uint64_t minimum_overall_smoothing_rate :22; ,
uint64_t reserved_3 : 2; ,
uint64_t maximum_overall_smoothing_rate :14; )
uint64_t maximum_overall_smoothing_rate :14; );
} __ucsi_packed;
/**

@ -37,7 +37,7 @@ struct dvb_pdc_descriptor {
struct descriptor d;
EBIT2(uint32_t reserved : 4; ,
uint32_t programme_id_label :20; )
uint32_t programme_id_label :20; );
} __ucsi_packed;
/**

@ -40,7 +40,7 @@ struct dvb_rnt_rar_over_dvb_stream_descriptor {
dvbdate_t last_valid_date;
EBIT3(uint8_t weighting : 6; ,
uint8_t complete_flag : 1; ,
uint8_t scheduled_flag : 1; )
uint8_t scheduled_flag : 1; );
uint16_t transport_stream_id;
uint16_t original_network_id;
uint16_t service_id;

@ -40,7 +40,7 @@ struct dvb_rnt_rar_over_ip_descriptor {
dvbdate_t last_valid_date;
EBIT3(uint8_t weighting : 6; ,
uint8_t complete_flag : 1; ,
uint8_t reserved : 1; )
uint8_t reserved : 1; );
uint8_t url_length;
/* uint8_t url[] */
} __ucsi_packed;

@ -24,8 +24,8 @@
struct dvb_rst_section * dvb_rst_section_codec(struct section *section)
{
uint8_t * buf = (uint8_t *) section;
int pos = sizeof(struct section);
int len = section_length(section);
size_t pos = sizeof(struct section);
size_t len = section_length(section);
struct dvb_rst_section * ret = (struct dvb_rst_section *) section;
while (pos < len) {

@ -82,7 +82,7 @@ struct dvb_rst_section *dvb_rst_section_codec(struct section *section);
static inline struct dvb_rst_status *
dvb_rst_section_statuses_first(struct dvb_rst_section *rst)
{
int pos = sizeof(struct dvb_rst_section);
size_t pos = sizeof(struct dvb_rst_section);
if (pos >= section_length(&rst->head))
return NULL;
@ -108,4 +108,3 @@ static inline struct dvb_rst_status *
#endif
#endif

@ -39,7 +39,7 @@ struct dvb_s2_satellite_delivery_descriptor {
EBIT4(uint8_t scrambling_sequence_selector : 1; ,
uint8_t multiple_input_stream : 1; ,
uint8_t backwards_compatability : 1; ,
uint8_t reserved : 5; )
uint8_t reserved : 5; );
/* uint32_t scrambling_sequence_index if scrambling_sequence_selector = 1 */
/* uint8_t input_stream_id if multiple_input_stream = 1 */
} __ucsi_packed;

@ -42,9 +42,9 @@ struct dvb_satellite_delivery_descriptor {
uint8_t polarization : 2; ,
uint8_t roll_off : 2; ,
uint8_t modulation_system : 1; ,
uint8_t modulation_type : 2; )
uint8_t modulation_type : 2; );
EBIT2(uint32_t symbol_rate : 28; , // BCD, units 100Hz
uint32_t fec_inner : 4; )
uint32_t fec_inner : 4; );
} __ucsi_packed;
/**

@ -24,8 +24,8 @@
struct dvb_sdt_section * dvb_sdt_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct dvb_sdt_section))
return NULL;

@ -109,7 +109,7 @@ static inline uint16_t dvb_sdt_section_transport_stream_id(struct dvb_sdt_sectio
static inline struct dvb_sdt_service *
dvb_sdt_section_services_first(struct dvb_sdt_section * sdt)
{
int pos = sizeof(struct dvb_sdt_section);
size_t pos = sizeof(struct dvb_sdt_section);
if (pos >= section_ext_length(&sdt->head))
return NULL;

@ -39,6 +39,7 @@ extern "C"
#include <libucsi/dvb/tot_section.h>
#include <libucsi/dvb/tva_container_section.h>
#include <libucsi/dvb/int_section.h>
#include <libucsi/dvb/mpe_fec_section.h>
/**
* The following are not implemented just now.

@ -37,7 +37,7 @@ struct dvb_service_availability_descriptor {
struct descriptor d;
EBIT2(uint8_t availability_flag : 1; ,
uint8_t reserved : 7; )
uint8_t reserved : 7; );
/* uint16_t cell_ids[] */
} __ucsi_packed;
@ -73,10 +73,10 @@ static inline struct dvb_service_availability_descriptor*
* @param d dvb_service_availability_descriptor pointer.
* @return Pointer to the field.
*/
static inline uint32_t *
static inline uint16_t *
dvb_service_availability_descriptor_cell_ids(struct dvb_service_availability_descriptor *d)
{
return (uint32_t *) ((uint8_t *) d + sizeof(struct dvb_service_availability_descriptor));
return (uint16_t *) ((uint8_t *) d + sizeof(struct dvb_service_availability_descriptor));
}
/**

@ -49,7 +49,14 @@ enum {
DVB_SERVICE_TYPE_EN50221 = 0x0d,
DVB_SERVICE_TYPE_RCS_MAP = 0x0e,
DVB_SERVICE_TYPE_RCS_FLS = 0x0f,
DVB_SERVICE_TYPE_MHP = 0x10
DVB_SERVICE_TYPE_MHP = 0x10,
DVB_SERVICE_TYPE_MPEG2_HD_DIGITAL_TV = 0x11,
DVB_SERVICE_TYPE_ADVANCED_CODEC_SD_DIGITAL_TV = 0x16,
DVB_SERVICE_TYPE_ADVANCED_CODEC_SD_NVOD_TIMESHIFT = 0x17,
DVB_SERVICE_TYPE_ADVANCED_CODEC_SD_NVOD_REF = 0x18,
DVB_SERVICE_TYPE_ADVANCED_CODEC_HD_DIGITAL_TV = 0x19,
DVB_SERVICE_TYPE_ADVANCED_CODEC_HD_NVOD_TIMESHIFT = 0x1a,
DVB_SERVICE_TYPE_ADVANCED_CODEC_HD_NVOD_REF = 0x1b,
};
/**

@ -37,7 +37,7 @@ struct dvb_short_smoothing_buffer_descriptor {
struct descriptor d;
EBIT2(uint8_t sb_size : 2; ,
uint8_t sb_leak_rate : 6; )
uint8_t sb_leak_rate : 6; );
/* uint8_t reserved [] */
} __ucsi_packed;

@ -25,8 +25,8 @@ struct dvb_sit_section * dvb_sit_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *) ext;
struct dvb_sit_section * ret = (struct dvb_sit_section *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct dvb_sit_section))
return NULL;
@ -67,4 +67,3 @@ struct dvb_sit_section * dvb_sit_section_codec(struct section_ext * ext)
return ret;
}

@ -125,7 +125,7 @@ static inline struct descriptor *
static inline struct dvb_sit_service *
dvb_sit_section_services_first(struct dvb_sit_section *sit)
{
int pos = sizeof(struct dvb_sit_section) + sit->transmission_info_loop_length;
size_t pos = sizeof(struct dvb_sit_section) + sit->transmission_info_loop_length;
if (pos >= section_ext_length(&sit->head))
return NULL;

@ -0,0 +1,116 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TARGET_IP_ADDRESS_DESCRIPTOR
#define _UCSI_DVB_TARGET_IP_ADDRESS_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_target_ip_address_descriptor structure.
*/
struct dvb_target_ip_address_descriptor {
struct descriptor d;
uint8_t ipv4_addr_mask[4];
/* struct dvb_ipv4_addr ipv4_addr[] */
} __ucsi_packed;
/**
* An entry in the ipv4_addr field of a dvb_target_ip_address_descriptor.
*/
struct dvb_ipv4_addr {
uint8_t ipv4_addr[4];
} __ucsi_packed;
/**
* Process a dvb_target_ip_address_descriptor.
*
* @param d Generic descriptor structure pointer.
* @return dvb_target_ip_address_descriptor pointer, or NULL on error.
*/
static inline struct dvb_target_ip_address_descriptor*
dvb_target_ip_address_descriptor_codec(struct descriptor* d)
{
uint32_t len = d->len - 4;
if (len % sizeof(struct dvb_ipv4_addr))
return NULL;
return (struct dvb_target_ip_address_descriptor*) d;
}
/**
* Iterator for entries in the ipv4_addr field of a dvb_target_ip_address_descriptor.
*
* @param d dvb_target_ip_address_descriptor pointer.
* @param pos Variable containing a pointer to the current dvb_ipv4_addr.
*/
#define dvb_target_ip_address_descriptor_ipv4_addr_for_each(d, pos) \
for ((pos) = dvb_target_ip_address_descriptor_ipv4_addr_first(d); \
(pos); \
(pos) = dvb_target_ip_address_descriptor_ipv4_addr_next(d, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ipv4_addr*
dvb_target_ip_address_descriptor_ipv4_addr_first(struct dvb_target_ip_address_descriptor *d)
{
if (d->d.len == 4)
return NULL;
return (struct dvb_ipv4_addr *)
((uint8_t*) d + sizeof(struct dvb_target_ip_address_descriptor));
}
static inline struct dvb_ipv4_addr*
dvb_target_ip_address_descriptor_ipv4_addr_next(struct dvb_target_ip_address_descriptor *d,
struct dvb_ipv4_addr *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len - 4;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv4_addr);
if (next >= end)
return NULL;
return (struct dvb_ipv4_addr *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,116 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TARGET_IP_SLASH_DESCRIPTOR
#define _UCSI_DVB_TARGET_IP_SLASH_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_target_ip_slash_descriptor structure.
*/
struct dvb_target_ip_slash_descriptor {
struct descriptor d;
/* struct dvb_ipv4_slash ipv4_slash[] */
} __ucsi_packed;
/**
* An entry in the ipv4_slash field of a dvb_target_ip_slash_descriptor.
*/
struct dvb_ipv4_slash {
uint8_t ipv4_addr[4];
uint8_t ipv4_slash;
} __ucsi_packed;
/**
* Process a dvb_target_ip_slash_descriptor.
*
* @param d Generic descriptor structure pointer.
* @return dvb_target_ip_slash_descriptor pointer, or NULL on error.
*/
static inline struct dvb_target_ip_slash_descriptor*
dvb_target_ip_slash_descriptor_codec(struct descriptor* d)
{
uint32_t len = d->len;
if (len % sizeof(struct dvb_ipv4_slash))
return NULL;
return (struct dvb_target_ip_slash_descriptor*) d;
}
/**
* Iterator for entries in the ipv4_slash field of a dvb_target_ip_slash_descriptor.
*
* @param d dvb_target_ip_slash_descriptor pointer.
* @param pos Variable containing a pointer to the current dvb_ipv4_slash.
*/
#define dvb_target_ip_slash_descriptor_ipv4_slash_for_each(d, pos) \
for ((pos) = dvb_target_ip_slash_descriptor_ipv4_slash_first(d); \
(pos); \
(pos) = dvb_target_ip_slash_descriptor_ipv4_slash_next(d, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ipv4_slash*
dvb_target_ip_slash_descriptor_ipv4_slash_first(struct dvb_target_ip_slash_descriptor *d)
{
if (d->d.len == 0)
return NULL;
return (struct dvb_ipv4_slash *)
((uint8_t*) d + sizeof(struct dvb_target_ip_slash_descriptor));
}
static inline struct dvb_ipv4_slash*
dvb_target_ip_slash_descriptor_ipv4_slash_next(struct dvb_target_ip_slash_descriptor *d,
struct dvb_ipv4_slash *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv4_slash);
if (next >= end)
return NULL;
return (struct dvb_ipv4_slash *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,118 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TARGET_IP_SOURCE_SLASH_DESCRIPTOR
#define _UCSI_DVB_TARGET_IP_SOURCE_SLASH_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_target_ip_source_slash_descriptor structure.
*/
struct dvb_target_ip_source_slash_descriptor {
struct descriptor d;
/* struct dvb_ipv4_source_slash ipv4_source_slash[] */
} __ucsi_packed;
/**
* An entry in the ipv4_source_slash field of a dvb_target_ip_source_slash_descriptor.
*/
struct dvb_ipv4_source_slash {
uint8_t ipv4_source_addr[4];
uint8_t ipv4_source_slash;
uint8_t ipv4_dest_addr[4];
uint8_t ipv4_dest_slash;
} __ucsi_packed;
/**
* Process a dvb_target_ip_source_slash_descriptor.
*
* @param d Generic descriptor structure pointer.
* @return dvb_target_ip_source_slash_descriptor pointer, or NULL on error.
*/
static inline struct dvb_target_ip_source_slash_descriptor*
dvb_target_ip_source_slash_descriptor_codec(struct descriptor* d)
{
uint32_t len = d->len;
if (len % sizeof(struct dvb_ipv4_source_slash))
return NULL;
return (struct dvb_target_ip_source_slash_descriptor*) d;
}
/**
* Iterator for entries in the ipv4_source_slash field of a dvb_target_ip_source_slash_descriptor.
*
* @param d dvb_target_ip_source_slash_descriptor pointer.
* @param pos Variable containing a pointer to the current dvb_ipv4_source_slash.
*/
#define dvb_target_ip_source_slash_descriptor_ipv4_source_slash_for_each(d, pos) \
for ((pos) = dvb_target_ip_source_slash_descriptor_ipv4_source_slash_first(d); \
(pos); \
(pos) = dvb_target_ip_source_slash_descriptor_ipv4_source_slash_next(d, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ipv4_source_slash*
dvb_target_ip_source_slash_descriptor_ipv4_source_slash_first(struct dvb_target_ip_source_slash_descriptor *d)
{
if (d->d.len == 0)
return NULL;
return (struct dvb_ipv4_source_slash *)
((uint8_t*) d + sizeof(struct dvb_target_ip_source_slash_descriptor));
}
static inline struct dvb_ipv4_source_slash*
dvb_target_ip_source_slash_descriptor_ipv4_source_slash_next(struct dvb_target_ip_source_slash_descriptor *d,
struct dvb_ipv4_source_slash *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv4_source_slash);
if (next >= end)
return NULL;
return (struct dvb_ipv4_source_slash *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,116 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TARGET_IPV6_ADDRESS_DESCRIPTOR
#define _UCSI_DVB_TARGET_IPV6_ADDRESS_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_target_ipv6_address_descriptor structure.
*/
struct dvb_target_ipv6_address_descriptor {
struct descriptor d;
uint8_t ipv6_addr_mask[16];
/* struct dvb_ipv6_addr ipv6_addr[] */
} __ucsi_packed;
/**
* An entry in the ipv6_addr field of a dvb_target_ipv6_address_descriptor.
*/
struct dvb_ipv6_addr {
uint8_t ipv6_addr[16];
} __ucsi_packed;
/**
* Process a dvb_target_ipv6_address_descriptor.
*
* @param d Generic descriptor structure pointer.
* @return dvb_target_ipv6_address_descriptor pointer, or NULL on error.
*/
static inline struct dvb_target_ipv6_address_descriptor*
dvb_target_ipv6_address_descriptor_codec(struct descriptor* d)
{
uint32_t len = d->len - 16;
if (len % sizeof(struct dvb_ipv6_addr))
return NULL;
return (struct dvb_target_ipv6_address_descriptor*) d;
}
/**
* Iterator for entries in the ipv6_addr field of a dvb_target_ipv6_address_descriptor.
*
* @param d dvb_target_ipv6_address_descriptor pointer.
* @param pos Variable containing a pointer to the current dvb_ipv6_addr.
*/
#define dvb_target_ipv6_address_descriptor_ipv6_addr_for_each(d, pos) \
for ((pos) = dvb_target_ipv6_address_descriptor_ipv6_addr_first(d); \
(pos); \
(pos) = dvb_target_ipv6_address_descriptor_ipv6_addr_next(d, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ipv6_addr*
dvb_target_ipv6_address_descriptor_ipv6_addr_first(struct dvb_target_ipv6_address_descriptor *d)
{
if (d->d.len == 16)
return NULL;
return (struct dvb_ipv6_addr *)
((uint8_t*) d + sizeof(struct dvb_target_ipv6_address_descriptor));
}
static inline struct dvb_ipv6_addr*
dvb_target_ipv6_address_descriptor_ipv6_addr_next(struct dvb_target_ipv6_address_descriptor *d,
struct dvb_ipv6_addr *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len - 16;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv6_addr);
if (next >= end)
return NULL;
return (struct dvb_ipv6_addr *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,116 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TARGET_IPV6_SLASH_DESCRIPTOR
#define _UCSI_DVB_TARGET_IPV6_SLASH_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_target_ipv6_slash_descriptor structure.
*/
struct dvb_target_ipv6_slash_descriptor {
struct descriptor d;
/* struct dvb_ipv6_slash ipv6_slash[] */
} __ucsi_packed;
/**
* An entry in the ipv6_slash field of a dvb_target_ipv6_slash_descriptor.
*/
struct dvb_ipv6_slash {
uint8_t ipv6_addr[16];
uint8_t ipv6_slash;
} __ucsi_packed;
/**
* Process a dvb_target_ipv6_slash_descriptor.
*
* @param d Generic descriptor structure pointer.
* @return dvb_target_ipv6_slash_descriptor pointer, or NULL on error.
*/
static inline struct dvb_target_ipv6_slash_descriptor*
dvb_target_ipv6_slash_descriptor_codec(struct descriptor* d)
{
uint32_t len = d->len;
if (len % sizeof(struct dvb_ipv6_slash))
return NULL;
return (struct dvb_target_ipv6_slash_descriptor*) d;
}
/**
* Iterator for entries in the ipv6_slash field of a dvb_target_ipv6_slash_descriptor.
*
* @param d dvb_target_ipv6_slash_descriptor pointer.
* @param pos Variable containing a pointer to the current dvb_ipv6_slash.
*/
#define dvb_target_ipv6_slash_descriptor_ipv6_slash_for_each(d, pos) \
for ((pos) = dvb_target_ipv6_slash_descriptor_ipv6_slash_first(d); \
(pos); \
(pos) = dvb_target_ipv6_slash_descriptor_ipv6_slash_next(d, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ipv6_slash*
dvb_target_ipv6_slash_descriptor_ipv6_slash_first(struct dvb_target_ipv6_slash_descriptor *d)
{
if (d->d.len == 0)
return NULL;
return (struct dvb_ipv6_slash *)
((uint8_t*) d + sizeof(struct dvb_target_ipv6_slash_descriptor));
}
static inline struct dvb_ipv6_slash*
dvb_target_ipv6_slash_descriptor_ipv6_slash_next(struct dvb_target_ipv6_slash_descriptor *d,
struct dvb_ipv6_slash *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv6_slash);
if (next >= end)
return NULL;
return (struct dvb_ipv6_slash *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,118 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TARGET_IPV6_SOURCE_SLASH_DESCRIPTOR
#define _UCSI_DVB_TARGET_IPV6_SOURCE_SLASH_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/**
* dvb_target_ipv6_source_slash_descriptor structure.
*/
struct dvb_target_ipv6_source_slash_descriptor {
struct descriptor d;
/* struct dvb_ipv6_source_slash ipv6_source_slash[] */
} __ucsi_packed;
/**
* An entry in the ipv6_source_slash field of a dvb_target_ipv6_source_slash_descriptor.
*/
struct dvb_ipv6_source_slash {
uint8_t ipv6_source_addr[16];
uint8_t ipv6_source_slash;
uint8_t ipv6_dest_addr[16];
uint8_t ipv6_dest_slash;
} __ucsi_packed;
/**
* Process a dvb_target_ipv6_source_slash_descriptor.
*
* @param d Generic descriptor structure pointer.
* @return dvb_target_ipv6_source_slash_descriptor pointer, or NULL on error.
*/
static inline struct dvb_target_ipv6_source_slash_descriptor*
dvb_target_ipv6_source_slash_descriptor_codec(struct descriptor* d)
{
uint32_t len = d->len;
if (len % sizeof(struct dvb_ipv6_source_slash))
return NULL;
return (struct dvb_target_ipv6_source_slash_descriptor*) d;
}
/**
* Iterator for entries in the ipv6_source_slash field of a dvb_target_ipv6_source_slash_descriptor.
*
* @param d dvb_target_ipv6_source_slash_descriptor pointer.
* @param pos Variable containing a pointer to the current dvb_ipv6_source_slash.
*/
#define dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_for_each(d, pos) \
for ((pos) = dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_first(d); \
(pos); \
(pos) = dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_next(d, pos))
/******************************** PRIVATE CODE ********************************/
static inline struct dvb_ipv6_source_slash*
dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_first(struct dvb_target_ipv6_source_slash_descriptor *d)
{
if (d->d.len == 0)
return NULL;
return (struct dvb_ipv6_source_slash *)
((uint8_t*) d + sizeof(struct dvb_target_ipv6_source_slash_descriptor));
}
static inline struct dvb_ipv6_source_slash*
dvb_target_ipv6_source_slash_descriptor_ipv6_source_slash_next(struct dvb_target_ipv6_source_slash_descriptor *d,
struct dvb_ipv6_source_slash *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len;
uint8_t *next = (uint8_t *) pos + sizeof(struct dvb_ipv6_source_slash);
if (next >= end)
return NULL;
return (struct dvb_ipv6_source_slash *) next;
}
#ifdef __cplusplus
}
#endif
#endif

@ -23,7 +23,7 @@
struct dvb_tdt_section * dvb_tdt_section_codec(struct section * section)
{
int len = section->length + sizeof(struct section);
size_t len = section_length(section);
struct dvb_tdt_section * ret = (struct dvb_tdt_section *) section;
if (len != sizeof(struct dvb_tdt_section))

@ -38,14 +38,14 @@ struct dvb_telephone_descriptor {
EBIT3(uint8_t reserved_1 : 2; ,
uint8_t foreign_availability : 1; ,
uint8_t connection_type : 5; )
uint8_t connection_type : 5; );
EBIT4(uint8_t reserved_2 : 1; ,
uint8_t country_prefix_length : 2; ,
uint8_t international_area_code_length : 3; ,
uint8_t operator_code_length : 2; )
uint8_t operator_code_length : 2; );
EBIT3(uint8_t reserved_3 : 1; ,
uint8_t national_area_code_length : 3; ,
uint8_t core_number_length : 4; )
uint8_t core_number_length : 4; );
/* uint8_t country_prefix[] */
/* uint8_t international_area_code[] */
/* uint8_t operator_code[] */

@ -39,7 +39,7 @@ enum {
DVB_TELETEXT_TYPE_SUBTITLE = 0x02,
DVB_TELETEXT_TYPE_ADDITIONAL = 0x03,
DVB_TELETEXT_TYPE_SCHEDULE = 0x04,
DVB_TELETEXT_TYPE_SUBTITLE_HEARING_IMPAIRED= 0x05
DVB_TELETEXT_TYPE_SUBTITLE_HEARING_IMPAIRED= 0x05,
};
/**
@ -57,7 +57,7 @@ struct dvb_teletext_descriptor {
struct dvb_teletext_entry {
iso639lang_t language_code;
EBIT2(uint8_t type : 5; ,
uint8_t magazine_number: 3; )
uint8_t magazine_number: 3; );
uint8_t page_number;
} __ucsi_packed;

@ -41,14 +41,14 @@ struct dvb_terrestrial_delivery_descriptor {
uint8_t priority : 1; ,
uint8_t time_slicing_indicator : 1; ,
uint8_t mpe_fec_indicator : 1; ,
uint8_t reserved_1 : 2; )
uint8_t reserved_1 : 2; );
EBIT3(uint8_t constellation : 2; ,
uint8_t hierarchy_information : 3; ,
uint8_t code_rate_hp_stream : 3; )
uint8_t code_rate_hp_stream : 3; );
EBIT4(uint8_t code_rate_lp_stream : 3; ,
uint8_t guard_interval : 2; ,
uint8_t transmission_mode : 2; ,
uint8_t other_frequency_flag : 1; )
uint8_t other_frequency_flag : 1; );
uint32_t reserved_2;
} __ucsi_packed;

@ -0,0 +1,94 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2008 Patrick Boettcher (pb@linuxtv.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_DVB_TIME_SLICE_FEC_IDENTIFIER_DESCRIPTOR
#define _UCSI_DVB_TIME_SLICE_FEC_IDENTIFIER_DESCRIPTOR 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/descriptor.h>
#include <libucsi/types.h>
/*
* dvb_time_slice_fec_identifier_descriptor structure.
*/
struct dvb_time_slice_fec_identifier_descriptor {
struct descriptor d;
EBIT4(uint8_t time_slicing :1; ,
uint8_t mpe_fec :2; ,
uint8_t reserved :2; ,
uint8_t frame_size :3; );
uint8_t max_burst_duration;
EBIT2(uint8_t max_average_rate :4; ,
uint8_t time_slice_fec_id :4; );
/* id_selector_bytes[] */
};
static inline struct dvb_time_slice_fec_identifier_descriptor *
dvb_time_slice_fec_identifier_descriptor_codec(struct descriptor* d)
{
if (d->len < 3)
return NULL;
return (struct dvb_time_slice_fec_identifier_descriptor *) d;
}
static inline uint8_t dvb_time_slice_fec_identifier_selector_byte_length(struct dvb_time_slice_fec_identifier_descriptor *d)
{
return d->d.len - 3;
}
static inline uint8_t * dvb_time_slice_fec_identifier_selector_bytes(struct dvb_time_slice_fec_identifier_descriptor *d)
{
if (d->d.len < 3)
return NULL;
else
return ((uint8_t *) d) + 2 + 3;
}
static inline uint16_t dvb_time_slice_fec_identifier_max_burst_duration_msec(struct dvb_time_slice_fec_identifier_descriptor *d)
{
return (d->max_burst_duration + 1) * 20;
}
static inline uint16_t dvb_time_slice_fec_identifier_frame_size_kbits(struct dvb_time_slice_fec_identifier_descriptor *d)
{
if (d->frame_size > 3)
return 0;
return (d->frame_size+1) * 512;
}
static inline uint16_t dvb_time_slice_fec_identifier_frame_size_rows(struct dvb_time_slice_fec_identifier_descriptor *d)
{
return dvb_time_slice_fec_identifier_frame_size_kbits(d) / 2;
}
#ifdef __cplusplus
}
#endif
#endif

@ -24,8 +24,8 @@
struct dvb_tot_section *dvb_tot_section_codec(struct section *section)
{
uint8_t * buf = (uint8_t *)section;
int pos = sizeof(struct section);
int len = section->length + sizeof(struct section) - CRC_SIZE;
size_t pos = sizeof(struct section);
size_t len = section_length(section) - CRC_SIZE;
struct dvb_tot_section * ret = (struct dvb_tot_section *)section;
if (len < sizeof(struct dvb_tot_section))
@ -34,7 +34,7 @@ struct dvb_tot_section *dvb_tot_section_codec(struct section *section)
pos += 5;
bswap16(buf + pos);
pos += 2;
if ((pos + ret->descriptors_loop_length) > len)
return NULL;

@ -23,7 +23,7 @@
struct dvb_tva_container_section *dvb_tva_container_section_codec(struct section_ext *ext)
{
int len = section_ext_length(ext);
size_t len = section_ext_length(ext);
struct dvb_tva_container_section* ret = (struct dvb_tva_container_section*) ext;
if (len < sizeof(struct dvb_tva_container_section))

@ -59,7 +59,7 @@ static inline uint16_t dvb_tva_container_section_container_id(struct dvb_tva_con
}
/**
* Accessor for the selector_byte field of a dvb_data_broadcast_id_descriptor.
* Accessor for the data field of a dvb_data_broadcast_id_descriptor.
*
* @param d dvb_data_broadcast_id_descriptor pointer.
* @return Pointer to the field.

@ -45,7 +45,7 @@ struct dvb_tva_id_descriptor {
struct dvb_tva_id_entry {
uint16_t tva_id;
EBIT2(uint8_t reserved : 5; ,
uint8_t running_status : 3; )
uint8_t running_status : 3; );
} __ucsi_packed;
/**
@ -105,7 +105,7 @@ static inline struct dvb_tva_id_entry*
}
static inline struct dvb_tva_id_entry*
dvb_tva_id_descriptor_countries_next(struct dvb_tva_id_descriptor *d,
dvb_tva_id_descriptor_entries_next(struct dvb_tva_id_descriptor *d,
struct dvb_tva_id_entry *pos)
{
uint8_t *end = (uint8_t*) d + 2 + d->d.len;

@ -40,7 +40,7 @@ enum {
DVB_RUNNING_STATUS_NOT_RUNNING = 0x01,
DVB_RUNNING_STATUS_FEW_SECONDS = 0x02,
DVB_RUNNING_STATUS_PAUSING = 0x03,
DVB_RUNNING_STATUS_RUNNING = 0x04
DVB_RUNNING_STATUS_RUNNING = 0x04,
};
/**

@ -39,7 +39,7 @@ enum {
DVB_VBI_DATA_SERVICE_ID_VPS = 0x04,
DVB_VBI_DATA_SERVICE_ID_WSS = 0x05,
DVB_VBI_DATA_SERVICE_ID_CC = 0x06,
DVB_VBI_DATA_SERVICE_ID_MONO_422 = 0x07
DVB_VBI_DATA_SERVICE_ID_MONO_422 = 0x07,
};
/**
@ -66,7 +66,7 @@ struct dvb_vbi_data_entry {
struct dvb_vbi_data_x {
EBIT3(uint8_t reserved : 2; ,
uint8_t field_parity : 1; ,
uint8_t line_offset : 5; )
uint8_t line_offset : 5; );
} __ucsi_packed;
/**

@ -46,7 +46,7 @@ struct dvb_vbi_teletext_descriptor {
struct dvb_vbi_teletext_entry {
iso639lang_t language_code;
EBIT2(uint8_t type : 5; ,
uint8_t magazine_number: 3; )
uint8_t magazine_number: 3; );
uint8_t page_number;
} __ucsi_packed;

@ -24,7 +24,7 @@
struct mpeg_cat_section * mpeg_cat_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *)ext;
int pos = sizeof(struct section_ext);
size_t pos = sizeof(struct section_ext);
if (verify_descriptors(buf + pos,
section_ext_length(ext) - sizeof(struct mpeg_cat_section)))

@ -69,7 +69,7 @@ extern struct mpeg_cat_section *mpeg_cat_section_codec(struct section_ext *secti
static inline struct descriptor *
mpeg_cat_section_descriptors_first(struct mpeg_cat_section *cat)
{
int pos = sizeof(struct mpeg_cat_section);
size_t pos = sizeof(struct mpeg_cat_section);
if (pos >= section_ext_length(&cat->head))
return NULL;

@ -0,0 +1,81 @@
/*
* section and descriptor parser
*
* Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
* Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
* Copyright (C) 2008 Patrick Boettcher (pb@linuxtv.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _UCSI_MPEG_DATAGRAM_SECTION_H
#define _UCSI_MPEG_DATAGRAM_SECTION_H 1
#ifdef __cplusplus
extern "C"
{
#endif
#include <libucsi/section.h>
/**
* datagram_section structure.
*/
struct datagram_section {
struct section head;
uint8_t MAC_address_6;
uint8_t MAC_address_5;
EBIT5(uint8_t reserved : 2; ,
uint8_t payload_scrambling_control : 2; ,
uint8_t address_scrambling_control : 2; ,
uint8_t LLC_SNAP_flag : 1; ,
uint8_t current_next_indicator : 1; );
uint8_t section_number;
uint8_t last_section_number;
uint8_t MAC_address_4;
uint8_t MAC_address_3;
uint8_t MAC_address_2;
uint8_t MAC_address_1;
/* LLC_SNAP or IP-data */
/* if last section stuffing */
/* CRC */
} __ucsi_packed;
/**
*/
static inline struct datagram_section *datagram_section_codec(struct section *section)
{
/* something to do here ? */
return (struct datagram_section *) section;
}
static inline uint8_t *datagram_section_ip_data(struct datagram_section *d)
{
return (uint8_t *) d + sizeof(struct section) + 2 + 1 + 1 + 1 + 4;
}
static inline size_t datagram_section_ip_data_length(struct datagram_section *d)
{
return section_length(&d->head) - (sizeof(struct section) + 2 + 1 + 1 + 1 + 4) - CRC_SIZE;
}
#ifdef __cplusplus
}
#endif
#endif

@ -25,4 +25,3 @@ struct mpeg_metadata_section * mpeg_metadata_section_codec(struct section_ext *
{
return (struct mpeg_metadata_section *)ext;
}

@ -25,8 +25,8 @@ struct mpeg_odsmt_section *mpeg_odsmt_section_codec(struct section_ext * ext)
{
struct mpeg_odsmt_section * odsmt = (struct mpeg_odsmt_section *)ext;
uint8_t * buf = (uint8_t *)ext;
int pos = sizeof(struct section_ext);
int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
int i;
if (len < sizeof(struct mpeg_odsmt_section))

@ -61,9 +61,9 @@ struct mpeg_odsmt_stream_multi
*/
struct mpeg_odsmt_stream {
union {
struct mpeg_odsmt_stream_single single __ucsi_packed;
struct mpeg_odsmt_stream_multi multi __ucsi_packed;
} u __ucsi_packed;
struct mpeg_odsmt_stream_single single;
struct mpeg_odsmt_stream_multi multi;
} u;
} __ucsi_packed;
/**
@ -118,7 +118,7 @@ static inline uint16_t mpeg_odsmt_section_pid(struct mpeg_odsmt_section *odsmt)
*/
static inline uint8_t*
mpeg_odsmt_section_object_descriptors(struct mpeg_odsmt_section * odsmt,
uint32_t* len);
size_t* len);
@ -133,7 +133,7 @@ static inline uint8_t*
static inline struct mpeg_odsmt_stream *
mpeg_odsmt_section_streams_first(struct mpeg_odsmt_section *odsmt)
{
int pos = sizeof(struct mpeg_odsmt_section);
size_t pos = sizeof(struct mpeg_odsmt_section);
if (pos >= section_ext_length(&odsmt->head))
return NULL;
@ -144,12 +144,12 @@ static inline struct mpeg_odsmt_stream *
static inline struct mpeg_odsmt_stream *
mpeg_odsmt_section_streams_next(struct mpeg_odsmt_section *odsmt,
struct mpeg_odsmt_stream *pos,
int index)
int _index)
{
uint8_t *end = (uint8_t*) odsmt + section_ext_length(&odsmt->head);
uint8_t *next;
if (index > odsmt->stream_count)
if (_index > odsmt->stream_count)
return NULL;
next = (uint8_t *) pos + sizeof(struct mpeg_odsmt_stream_multi) +
@ -198,13 +198,13 @@ static inline struct descriptor *
static inline uint8_t*
mpeg_odsmt_section_object_descriptors(struct mpeg_odsmt_section * odsmt,
uint32_t* len)
size_t* len)
{
struct mpeg_odsmt_stream* pos;
int size = sizeof(struct mpeg_odsmt_section);
int index;
size_t size = sizeof(struct mpeg_odsmt_section);
int _index;
mpeg_odsmt_section_streams_for_each(odsmt, pos, index) {
mpeg_odsmt_section_streams_for_each(odsmt, pos, _index) {
if (odsmt->stream_count == 0)
size += sizeof(struct mpeg_odsmt_stream_single) +
pos->u.single.es_info_length;

@ -24,8 +24,8 @@
struct mpeg_pat_section *mpeg_pat_section_codec(struct section_ext * ext)
{
uint8_t *buf = (uint8_t *)ext;
int pos = sizeof(struct section_ext);
int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct mpeg_pat_section))
return NULL;

@ -44,7 +44,7 @@ struct mpeg_pat_section {
struct mpeg_pat_program {
uint16_t program_number;
EBIT2(uint16_t reserved : 3; ,
uint16_t pid :13; )
uint16_t pid :13; );
} __ucsi_packed;
/**
@ -90,7 +90,7 @@ static inline uint16_t mpeg_pat_section_transport_stream_id(struct mpeg_pat_sect
static inline struct mpeg_pat_program *
mpeg_pat_section_programs_first(struct mpeg_pat_section * pat)
{
int pos = sizeof(struct mpeg_pat_section);
size_t pos = sizeof(struct mpeg_pat_section);
if (pos >= section_ext_length(&pat->head))
return NULL;

@ -25,8 +25,8 @@ struct mpeg_pmt_section * mpeg_pmt_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *) ext;
struct mpeg_pmt_section * pmt = (struct mpeg_pmt_section *) ext;
unsigned int pos = sizeof(struct section_ext);
unsigned int len = section_ext_length(ext);
size_t pos = sizeof(struct section_ext);
size_t len = section_ext_length(ext);
if (len < sizeof(struct mpeg_pmt_section))
return NULL;

@ -36,9 +36,9 @@ struct mpeg_pmt_section {
struct section_ext head;
EBIT2(uint16_t reserved_1 : 3; ,
uint16_t pcr_pid :13; )
uint16_t pcr_pid :13; );
EBIT2(uint16_t reserved_2 : 4; ,
uint16_t program_info_length :12; )
uint16_t program_info_length :12; );
/* struct descriptor descriptors[] */
/* struct mpeg_pmt_stream streams[] */
} __ucsi_packed;
@ -49,9 +49,9 @@ struct mpeg_pmt_section {
struct mpeg_pmt_stream {
uint8_t stream_type;
EBIT2(uint16_t reserved_1 : 3; ,
uint16_t pid :13; )
uint16_t pid :13; );
EBIT2(uint16_t reserved_2 : 4; ,
uint16_t es_info_length :12; )
uint16_t es_info_length :12; );
/* struct descriptor descriptors[] */
} __ucsi_packed;
@ -66,7 +66,7 @@ extern struct mpeg_pmt_section *mpeg_pmt_section_codec(struct section_ext *secti
/**
* Accessor for program_number field of a PMT.
*
*
* @param pmt PMT pointer.
* @return The program_number.
*/
@ -140,7 +140,7 @@ static inline struct descriptor *
static inline struct mpeg_pmt_stream *
mpeg_pmt_section_streams_first(struct mpeg_pmt_section * pmt)
{
int pos = sizeof(struct mpeg_pmt_section) + pmt->program_info_length;
size_t pos = sizeof(struct mpeg_pmt_section) + pmt->program_info_length;
if (pos >= section_ext_length(&pmt->head))
return NULL;

@ -33,6 +33,7 @@ extern "C"
#include <libucsi/mpeg/pmt_section.h>
#include <libucsi/mpeg/tsdt_section.h>
#include <libucsi/mpeg/metadata_section.h>
#include <libucsi/mpeg/datagram_section.h>
#define TRANSPORT_PAT_PID 0x00
#define TRANSPORT_CAT_PID 0x01
@ -48,7 +49,8 @@ enum mpeg_section_tag {
stag_mpeg_transport_stream_description = 0x03,
stag_mpeg_iso14496_scene_description = 0x04,
stag_mpeg_iso14496_object_description = 0x05,
stag_mpeg_metadata = 0x06
stag_mpeg_metadata = 0x06,
stag_mpeg_datagram = 0x3e,
};
#ifdef __cplusplus

@ -24,7 +24,7 @@
struct mpeg_tsdt_section * mpeg_tsdt_section_codec(struct section_ext * ext)
{
uint8_t * buf = (uint8_t *)ext;
int pos = sizeof(struct section_ext);
size_t pos = sizeof(struct section_ext);
if (verify_descriptors(buf + pos,
section_ext_length(ext) - sizeof(struct mpeg_tsdt_section)))
@ -32,4 +32,3 @@ struct mpeg_tsdt_section * mpeg_tsdt_section_codec(struct section_ext * ext)
return (struct mpeg_tsdt_section *)ext;
}

@ -70,7 +70,7 @@ extern struct mpeg_tsdt_section *mpeg_tsdt_section_codec(struct section_ext *sec
static inline struct descriptor *
mpeg_tsdt_section_descriptors_first(struct mpeg_tsdt_section * tsdt)
{
int pos = sizeof(struct mpeg_tsdt_section);
size_t pos = sizeof(struct mpeg_tsdt_section);
if (pos >= section_ext_length(&tsdt->head))
return NULL;

@ -43,7 +43,7 @@ struct section {
EBIT4(uint16_t syntax_indicator : 1; ,
uint16_t private_indicator : 1; , /* 2.4.4.10 */
uint16_t reserved : 2; ,
uint16_t length :12; )
uint16_t length :12; );
} __ucsi_packed;
/**
@ -54,12 +54,12 @@ struct section_ext {
EBIT4(uint16_t syntax_indicator : 1; ,
uint16_t private_indicator : 1; , /* 2.4.4.10 */
uint16_t reserved : 2; ,
uint16_t length :12; )
uint16_t length :12; );
uint16_t table_id_ext;
EBIT3(uint8_t reserved1 : 2; ,
uint8_t version_number : 5; ,
uint8_t current_next_indicator : 1; )
uint8_t current_next_indicator : 1; );
uint8_t section_number;
uint8_t last_section_number;
} __ucsi_packed;
@ -75,6 +75,29 @@ struct psi_table_state {
} __ucsi_packed;
/**
* Determine the total length of a section, including the header.
*
* @param section The parsed section structure.
* @return The length.
*/
static inline size_t section_length(struct section *section)
{
return section->length + sizeof(struct section);
}
/**
* Determine the total length of an extended section, including the header,
* but omitting the CRC.
*
* @param section The parsed section_ext structure.
* @return The length.
*/
static inline size_t section_ext_length(struct section_ext * section)
{
return section->length + sizeof(struct section) - CRC_SIZE;
}
/**
* Process a section structure in-place.
*
@ -82,7 +105,7 @@ struct psi_table_state {
* @param len Length of data.
* @return Pointer to the section structure, or NULL if invalid.
*/
static inline struct section * section_codec(uint8_t * buf, int len)
static inline struct section * section_codec(uint8_t * buf, size_t len)
{
struct section * ret = (struct section *)buf;
@ -91,7 +114,7 @@ static inline struct section * section_codec(uint8_t * buf, int len)
bswap16(buf+1);
if (len != ret->length + 3)
if (len != ret->length + 3U)
return NULL;
return ret;
@ -107,7 +130,7 @@ static inline struct section * section_codec(uint8_t * buf, int len)
static inline int section_check_crc(struct section *section)
{
uint8_t * buf = (uint8_t *) section;
int len = sizeof(struct section) + section->length;
size_t len = section_length(section);
uint32_t crc;
/* the crc check has to be performed on the unswapped data */
@ -167,12 +190,9 @@ static inline struct section_ext * section_ext_encode(struct section_ext* sectio
int len = sizeof(struct section) + section->length;
uint32_t crc;
/* zap the current CRC value */
memset(buf+len-4, 0, 4);
/* the crc has to be performed on the swapped data */
bswap16(buf+1);
crc = crc32(CRC32_INIT, buf, len);
crc = crc32(CRC32_INIT, buf, len-4);
bswap16(buf+1);
/* update the CRC */
@ -183,29 +203,6 @@ static inline struct section_ext * section_ext_encode(struct section_ext* sectio
return (struct section_ext *)section;
}
/**
* Determine the total length of a section, including the header.
*
* @param section The parsed section structure.
* @return The length.
*/
static inline int section_length(struct section *section)
{
return section->length + sizeof(struct section);
}
/**
* Determine the total length of an extended section, including the header,
* but omitting the CRC.
*
* @param section The parsed section_ext structure.
* @return The length.
*/
static inline int section_ext_length(struct section_ext * section)
{
return section->length + sizeof(struct section) - CRC_SIZE;
}
/**
* Reset a psi_table_state structure.
*
@ -227,7 +224,10 @@ static inline int section_ext_useful(struct section_ext *section, struct psi_tab
{
if ((section->version_number == tstate->version_number) && tstate->complete)
return 0;
if ((section->version_number != tstate->version_number) && (section->section_number == 0)) {
if (section->version_number != tstate->version_number) {
if (section->section_number != 0)
return 0;
tstate->next_section_number = 0;
tstate->complete = 0;
tstate->version_number = section->version_number;

@ -54,11 +54,10 @@ struct section_buf {
extern int section_buf_init(struct section_buf *section, int max);
/**
* Initialise a section_buf structure.
* Reset a section_buf structure (e.g. if a discontinuity occurred). The
* section_buf will wait for the first PDU start indicator.
*
* @param section The section_buf to initialise.
* @param max Maximum number of bytes in section (must be > 3)
* @return 0 on success, nonzero on error.
* @param section The section_buf to reset.
*/
static inline void section_buf_reset(struct section_buf *section)
{

@ -145,7 +145,7 @@ static inline int transport_packet_pid(struct transport_packet *pkt)
/**
* Process a buffer into a transport packet.
*
* @param buf Raw buffer.
* @param buf Raw buffer. Note, this function assumes there are 188 bytes available.
* @return transport_packet pointer, or NULL on error.
*/
static inline struct transport_packet *transport_packet_init(unsigned char *buf)

@ -141,6 +141,9 @@ bool KaffeineDVBsection::doIconv( QCString &s, QCString table, char *buffer, int
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;

@ -109,13 +109,15 @@ ScanDialog::ScanDialog( QPtrList<DvbStream> *d, QPtrList<ChannelDesc> *ch, QSize
foundList->clear();
foundList->setAllColumnsShowFocus( true );
foundList->setSelectionMode( QListView::Extended );
channelsList->setSorting( 0 );
channelsList->setSorting( 1 ); // sort by source 1st than channel name
channelsList->setAllColumnsShowFocus( true );
channelsList->setSelectionMode( QListView::Extended );
ChannelDesc *chan;
QListViewItem *it;
for ( int i=0; i<(int)chandesc->count(); i++ ) {
chan = chandesc->at(i);
it = new QListViewItem( channelsList, chan->name );
it = new QListViewItem( channelsList, chan->name, chan->tp.source );
if ( !chan->pix.isNull() )
it->setPixmap( 0, chan->pix );
else {
@ -425,7 +427,11 @@ void ScanDialog::parseTp( QString s, fe_type_t type, QString src )
trans->type=FE_QAM;
trans->source = "Cable";
}
else {
else if ( s.left(pos)=="A" ) {
trans->type=FE_ATSC;
trans->source = "ATSC Terrestrial";
}
else if ( s.left(pos)=="S" ) {
trans->type=FE_QPSK;
trans->source = src;
}
@ -439,14 +445,15 @@ void ScanDialog::parseTp( QString s, fe_type_t type, QString src )
trans->freq = s.left(pos).toULong()/1000;
s = s.right( s.length()-pos-1 );
s = s.stripWhiteSpace();
pos = s.find(" ");
if ( trans->type!=FE_ATSC )
pos = s.find(" ");
if ( trans->type==FE_QPSK ) {
trans->pol = s.left(pos).lower()[0].latin1();
s = s.right( s.length()-pos-1 );
s = s.stripWhiteSpace();
pos = s.find(" ");
}
if ( trans->type!=FE_OFDM ) {
if ( trans->type!=FE_OFDM && trans->type!=FE_ATSC ) {
trans->sr = s.left(pos).toULong()/1000;
}
else {
@ -459,6 +466,27 @@ void ScanDialog::parseTp( QString s, fe_type_t type, QString src )
else
trans->bandwidth = BANDWIDTH_AUTO;
}
if ( trans->type==FE_ATSC ) {
if ( s.left(pos)=="8VSB" )
trans->modulation = VSB_8;
else if ( s.left(pos)=="16VSB" )
trans->modulation = VSB_16;
else if ( s.left(pos)=="QAM16" )
trans->modulation = QAM_16;
else if ( s.left(pos)=="QAM32" )
trans->modulation = QAM_32;
else if ( s.left(pos)=="QAM64" )
trans->modulation = QAM_64;
else if ( s.left(pos)=="QAM128" )
trans->modulation = QAM_128;
else if ( s.left(pos)=="QAM256" )
trans->modulation = QAM_256;
else
trans->modulation = QAM_AUTO;
transponders.append( trans );
return;
}
s = s.right( s.length()-pos-1 );
s = s.stripWhiteSpace();
pos = s.find(" ");
@ -584,7 +612,17 @@ bool ScanDialog::getTransData()
if ( searchComb->currentText().startsWith("AUTO") ) {
int i;
for ( i=402; i<900; i+=8 ) {
for ( i=177; i<227; i+=7 ) {
if ( offset07->isChecked() ) {
s = QString("T %1 7MHz AUTO AUTO AUTO AUTO AUTO AUTO").arg( (i*1000000)+500000 );
parseTp( s, ds->getType(), "" );
}
if ( offset125p->isChecked() ) {
s = QString("T %1 7MHz AUTO AUTO AUTO AUTO AUTO AUTO").arg( (i*1000000)+500000+125000 );
parseTp( s, ds->getType(), "" );
}
}
for ( i=474; i<859; i+=8 ) {
if ( offset167m->isChecked() ) {
s = QString("T %1 8MHz AUTO AUTO AUTO AUTO AUTO AUTO").arg( (i*1000000)-167000 );
parseTp( s, ds->getType(), "" );
@ -605,7 +643,9 @@ bool ScanDialog::getTransData()
case FE_QPSK : s += "dvb-s/"; break;
case FE_QAM : s += "dvb-c/"; break;
case FE_OFDM : s += "dvb-t/"; break;
case FE_ATSC : return false;
case FE_ATSC : s += "atsc/"; break;
default:
return false;
}
s += searchComb->currentText();
QFile f( s );
@ -713,7 +753,9 @@ void ScanDialog::addSelected()
if(checkChannUpdate(chan)){
checkDuplicateName( chan );
chan->num = chandesc->count()+1;
if (chan->num == 0) {
chan->num = chandesc->count()+1;
}
chandesc->append( new ChannelDesc( *chan ) );
it = new QListViewItem( channelsList, chan->name );
if ( chan->type==1 ) {

@ -8,8 +8,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>725</width>
<height>560</height>
<width>790</width>
<height>578</height>
</rect>
</property>
<property name="caption">
@ -21,7 +21,7 @@
</property>
<widget class="QLayoutWidget" row="0" column="0">
<property name="name">
<cstring>layout10</cstring>
<cstring>layout9</cstring>
</property>
<vbox>
<property name="name">
@ -29,7 +29,7 @@
</property>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout9</cstring>
<cstring>layout8</cstring>
</property>
<hbox>
<property name="name">
@ -66,9 +66,28 @@
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>Source</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<property name="name">
<cstring>channelsList</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>3</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
@ -123,38 +142,51 @@
<property name="title">
<string>Search On</string>
</property>
<vbox>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QComboBox">
<widget class="QComboBox" row="0" column="0">
<property name="name">
<cstring>searchComb</cstring>
</property>
</widget>
<widget class="QGroupBox">
<widget class="QGroupBox" row="1" column="0">
<property name="name">
<cstring>offsetGroup</cstring>
</property>
<property name="title">
<string>Offset (KHz)</string>
</property>
<hbox>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QCheckBox">
<widget class="QCheckBox" row="1" column="3">
<property name="name">
<cstring>offset0</cstring>
<cstring>offset167m</cstring>
</property>
<property name="text">
<string>0</string>
<string>-167</string>
</property>
<property name="checked">
<bool>true</bool>
</widget>
<widget class="QLabel" row="0" column="0">
<property name="name">
<cstring>textLabel2</cstring>
</property>
<property name="text">
<string>(7MHz)</string>
</property>
</widget>
<widget class="QCheckBox">
<widget class="QLabel" row="1" column="0">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="text">
<string>(8MHz)</string>
</property>
</widget>
<widget class="QCheckBox" row="1" column="2">
<property name="name">
<cstring>offset167p</cstring>
</property>
@ -162,17 +194,39 @@
<string>+167</string>
</property>
</widget>
<widget class="QCheckBox">
<widget class="QCheckBox" row="0" column="2" rowspan="1" colspan="2">
<property name="name">
<cstring>offset167m</cstring>
<cstring>offset125p</cstring>
</property>
<property name="text">
<string>-167</string>
<string>+125</string>
</property>
</widget>
</hbox>
<widget class="QCheckBox" row="1" column="1">
<property name="name">
<cstring>offset0</cstring>
</property>
<property name="text">
<string>0</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QCheckBox" row="0" column="1">
<property name="name">
<cstring>offset07</cstring>
</property>
<property name="text">
<string>0</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</grid>
</widget>
</vbox>
</grid>
</widget>
<widget class="QPushButton">
<property name="name">
@ -206,7 +260,7 @@
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
<height>18</height>
</size>
</property>
</spacer>
@ -231,210 +285,190 @@
<property name="sizeHint">
<size>
<width>21</width>
<height>20</height>
<height>19</height>
</size>
</property>
</spacer>
<widget class="QLayoutWidget">
<widget class="QGroupBox">
<property name="name">
<cstring>layout38</cstring>
<cstring>filtersGroup</cstring>
</property>
<property name="title">
<string>Filters</string>
</property>
<vbox>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QGroupBox">
<widget class="QCheckBox" row="2" column="0">
<property name="name">
<cstring>filtersGroup</cstring>
<cstring>radioCb</cstring>
</property>
<property name="title">
<string>Filters</string>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Radio</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>ftaCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Free to air</string>
</property>
</widget>
<widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>radioCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Radio</string>
</property>
</widget>
<widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>tvCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TV</string>
</property>
</widget>
<widget class="QCheckBox" row="3" column="0">
<property name="name">
<cstring>providerCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Provider:</string>
</property>
</widget>
<widget class="QComboBox" row="3" column="1">
<property name="name">
<cstring>providerComb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</grid>
</widget>
<widget class="QPushButton">
<widget class="QCheckBox" row="1" column="0">
<property name="name">
<cstring>addselectedBtn</cstring>
<cstring>tvCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>1</hsizetype>
<hsizetype>4</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;&lt; Add Selected</string>
<string>TV</string>
</property>
</widget>
<widget class="QPushButton">
<widget class="QCheckBox" row="3" column="0">
<property name="name">
<cstring>addfilteredBtn</cstring>
<cstring>providerCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>1</hsizetype>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;&lt; Add Filtered</string>
<string>Provider:</string>
</property>
</widget>
</vbox>
</widget>
</vbox>
</widget>
<widget class="QGroupBox">
<property name="name">
<cstring>groupBox11</cstring>
</property>
<property name="title">
<string>Found</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout8</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QListView">
<column>
<property name="text">
<string>SNR</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<widget class="QComboBox" row="3" column="1">
<property name="name">
<cstring>foundList</cstring>
<cstring>providerComb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>3</vsizetype>
<hsizetype>3</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QPushButton">
<widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>selectallBtn</cstring>
<cstring>ftaCb</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select All</string>
<string>Free to air</string>
</property>
</widget>
</vbox>
</grid>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>addselectedBtn</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>1</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;&lt; Add Selected</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>addfilteredBtn</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>1</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;&lt; Add Filtered</string>
</property>
</widget>
</vbox>
</widget>
<widget class="QGroupBox">
<property name="name">
<cstring>groupBox11</cstring>
</property>
<property name="title">
<string>Found</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QListView" row="0" column="0">
<column>
<property name="text">
<string>SNR</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<property name="name">
<cstring>foundList</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>3</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QPushButton" row="1" column="0">
<property name="name">
<cstring>selectallBtn</cstring>
</property>
<property name="text">
<string>Select All</string>
</property>
</widget>
</grid>
</widget>
</hbox>
</widget>
<widget class="Line">

@ -345,7 +345,12 @@ void Ts2Rtp::psiTables( QPtrList<ChannelDesc> *channels )
buf[off++] = 0x01; // current_next_indicator
buf[off++] = 0x00; // section_number
buf[off++] = 0x00; // last_section_number
buf[off++] = desc->vpid>>8; buf[off++] = desc->vpid&0xff; // PCR pid
if ( desc->vpid ) {
buf[off++] = desc->vpid>>8; buf[off++] = desc->vpid&0xff; // PCR pid
}
else if ( desc->napid ) {
buf[off++] = desc->apid[0].pid>>8; buf[off++] = desc->apid[0].pid&0xff; // PCR pid
}
buf[off++] = 0x00; buf[off++] = 0x00; // infos_length
if ( desc->vpid ) {
buf[off++] = desc->vType; // stream_type

@ -158,14 +158,13 @@ Kaffeine::Kaffeine() : DCOPObject("KaffeineIface"),
//statusBar()->insertItem(i18n("Entries: %1, Playtime: %2").arg("0").arg("0:00:00"), 9, 0, true);
//statusBar()->insertItem(i18n("No player"), 10, 0, true);
QString stamp = locate("appdata", "wizard_stamp_v0.7.1");
QString localStamp = locateLocal("appdata", "wizard_stamp_v0.7.1");
QString stamp = locateLocal("appdata", "wizard_stamp_v0.7.1");
if ((!QFile::exists(stamp)) || args->isSet("wizard"))
{
InstWizard::showWizard();
KProcess process;
process << "touch" << localStamp;
process << "touch" << stamp;
process.start(KProcess::Block, KProcess::Stderr);
process.clearArguments();
}
@ -308,8 +307,10 @@ void Kaffeine::updateArgs()
}
loadTMP(urls);
if (args->isSet("fullscreen"))
if (args->isSet("fullscreen")) {
inplug->showPlayer();
fullscreen();
}
if (args->isSet("minimal"))
minimal();
@ -360,7 +361,7 @@ void Kaffeine::slotLoadPart(const QString& desktopName)
{
kdDebug() << "Kaffeine:: Try to load service: " << desktopName << endl;
if (desktopName == m_currentPartService && m_mediaPart != NULL)
if (desktopName == m_currentPartService)
return;
KService::Ptr service = KService::serviceByDesktopName(desktopName);
@ -443,7 +444,6 @@ void Kaffeine::slotLoadPart(const QString& desktopName)
}
}
inplug->setPlayerContainer( m_playerContainer );
m_playerContainer->show();
}
void Kaffeine::slotLoadingCanceled(const QString& message)
@ -694,7 +694,7 @@ void Kaffeine::setupActions()
QStringList mediaParts;
// check for kaffeine parts
KTrader::OfferList offers = KTrader::self()->query("application/x-mplayer2", "'KaffeinePart' in ServiceTypes");
KTrader::OfferList offers = KTrader::self()->query("audio/x-mp3", "'KaffeinePart' in ServiceTypes");
KTrader::OfferList::Iterator end(offers.end());
for(KTrader::OfferList::Iterator it = offers.begin(); it != end; ++it)
{
@ -1899,15 +1899,3 @@ int Kaffeine::dvbSNR( int device )
#endif
return -1;
}
void Kaffeine::reloadEngine()
{
bool isPlaying = m_mediaPart ? m_mediaPart->isPlaying() : false;
unloadCurrentPart();
kapp->config()->setGroup("Player Part");
slotLoadPart(kapp->config()->readEntry("Last Service Desktop Name", DEFAULT_PLAYER_PART));
if (isPlaying)
slotPlaylistPlay();
}

@ -1,8 +1,6 @@
[Desktop Entry]
Categories=Qt;KDE;Application;AudioVideo;Player;
X-KDE-Protocols=file,http,audiocd,smb
Categories=Qt;KDE;AudioVideo;Player;
DocPath=kaffeine/index.html
Encoding=UTF-8
Exec=kaffeine %U
GenericName=Media Player
GenericName[af]=Media Speler
@ -43,13 +41,13 @@ GenericName[sr@Latn]=Medija plejer
GenericName[sv]=Mediaspelare
GenericName[tg]=Навозишгари Медиа
GenericName[th]=โปรแกรมเล่นสื่อ
GenericName[tr]=Oynatıcı
GenericName[tr]=Çokluortam Oynatıcı
GenericName[uk]=Програвач медіа
GenericName[xx]=xxMedia Playerxx
GenericName[zh_CN]=媒体播放器
GenericName[zh_TW]=媒體播放程式
Icon=kaffeine
MimeType=application/x-ogg;video/x-matroska;audio/x-matroska;video/mpeg;video/msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-avi;video/x-fli;video/x-flic;video/x-ms-asf;video/x-ms-wmv;video/x-msvideo;application/x-mplayer2;application/smil;application/x-kaffeine;audio/x-musepack;
MimeType=application/x-ogg;audio/basic;audio/vnd.rn-realaudio;audio/x-aiff;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-ogg;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;audio/x-scpls;audio/x-wav;audio/x-flac;video/x-matroska;audio/x-matroska;video/mpeg;video/msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-avi;video/x-fli;video/x-flic;video/x-ms-asf;video/x-ms-wmv;video/x-msvideo;application/x-mplayer2;application/smil;application/x-kaffeine;audio/x-musepack;audio/x-mod;audio/x-stm;
Name=Kaffeine
Name[bn]=ক্যাফিন
Name[pa]=ਕੈਫ਼ੀਨ

@ -121,7 +121,6 @@ private:
void dvbOSDPreviousProgram();
void dvbOSDZap();
void playDvb();
void reloadEngine();
public slots:
void slotPlay(const MRL&);

@ -109,10 +109,6 @@
<name>Recall</name>
<comment>Recall last DVB channel.</comment>
</action>
<action objid="KaffeineIface" prototype="void reloadEngine()">
<name>reloadEngine</name>
<comment>Reload current engine</comment>
</action>
<action objid="XinePartIface" prototype="void dvdMenuSelect()">
<name>dvdMenuSelect</name>
<comment>Select Dvd Menu.</comment>

@ -134,8 +134,6 @@ k_dcop:
virtual void dvbOSDZap() = 0;
virtual void playDvb() = 0;
virtual void reloadEngine() = 0;
};
#endif /* KAFFEINEIFACE_H */

@ -77,6 +77,7 @@ int main(int argc, char *argv[])
/* FIXME: what about the other contributors listed in CREDITS? --pfister */
aboutData.addCredit("Devin J. Heitmuelle", I18N_NOOP("ATSC scanning."), "devin.heitmueller@gmail.com");
aboutData.addCredit("Eldon Tyrell", I18N_NOOP("DVB patches."), "dr.e.tyrell@gmail.com");
aboutData.addCredit("Michael Hoertnagl", I18N_NOOP("Various patches."), "mtron@a1.net");
aboutData.addCredit("Ricardo Manuel Santos Rodrigues", I18N_NOOP("Various patches."), "madinfo@cadaval.net");
@ -89,7 +90,6 @@ int main(int argc, char *argv[])
aboutData.addCredit("Miguel Freitas", I18N_NOOP("xine post plugin handling. Many patches."), "miguel@cetuc.puc-rio.br");
aboutData.addCredit("Giorgos Gousios", I18N_NOOP("Subtitle file import."), "gousiosg@cs.man.ac.uk");
aboutData.addCredit("Michael Rolf", I18N_NOOP("M3U import. Testing."), "mi.rolf@gmx.net");
aboutData.addCredit("Sergey Rudchenko", I18N_NOOP("Automatic codec installation"), "sergey.rudchenko@gmail.com");
KCmdLineArgs::init(argc, argv, &aboutData);
KCmdLineArgs::addCmdLineOptions(cmdLineOptions);

@ -0,0 +1,825 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 483858 $
# kaffeine/src/player-parts/dummy-part/Makefile. Generated from Makefile.in by configure.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
srcdir = .
top_srcdir = ../../../..
pkgdatadir = $(datadir)/kaffeine-0.8.8
pkglibdir = $(libdir)/kaffeine-0.8.8
pkgincludedir = $(includedir)/kaffeine-0.8.8
top_builddir = ../../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = /usr/bin/install -c -p
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = i686-pc-linux-gnu
host_triplet = i686-pc-linux-gnu
target_triplet = i686-pc-linux-gnu
ACLOCAL = ${SHELL} /partage/Linux/site/tmp/kaffeine-0.8.8/admin/missing --run aclocal-1.7
AMDEP_FALSE = #
AMDEP_TRUE =
AMTAR = ${SHELL} /partage/Linux/site/tmp/kaffeine-0.8.8/admin/missing --run tar
AR = ar
ARTSCCONFIG =
AUTOCONF = $(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure
AUTODIRS =
AUTOHEADER = ${SHELL} /partage/Linux/site/tmp/kaffeine-0.8.8/admin/missing --run autoheader
AUTOMAKE = ${SHELL} /partage/Linux/site/tmp/kaffeine-0.8.8/admin/missing --run automake-1.7
AWK = gawk
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -O2 -Wformat-security -Wmissing-format-attribute
CFLAGS_DPMS =
CFLAGS_GSTREAMER =
CFLAGS_OGGVORBIS =
CFLAGS_XCB =
CFLAGS_XINE =
CFLAGS_XINERAMA =
CFLAGS_XTEST =
CONF_FILES = $(top_srcdir)/./admin/configure.in.min $(top_srcdir)/configure.in.in $(top_srcdir)/./kaffeine/configure.in.bot $(top_srcdir)/./kaffeine/configure.in.in
CPP = gcc -E
CPPFLAGS = -DQT_THREAD_SUPPORT -D_REENTRANT
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -Wno-long-long -Wundef -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -O2 -Wformat-security -Wmissing-format-attribute -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION
CYGPATH_W = echo
DCOPIDL = /usr/bin/dcopidl
DCOPIDL2CPP = /usr/bin/dcopidl2cpp
DCOPIDLNG = /usr/bin/dcopidlng
DCOP_DEPENDENCIES = $(DCOPIDL) $(DCOPIDLNG)
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
DOXYGEN =
DOXYGEN_PROJECT_NAME = The API Reference
DOXYGEN_PROJECT_NUMBER = Version 3.5.7
ECHO = echo
ECHO_C =
ECHO_N = -n
ECHO_T =
EGREP = /bin/grep -E
ENABLE_PERMISSIVE_FLAG = -fpermissive
EXEEXT =
F77 =
FFLAGS =
FRAMEWORK_COREAUDIO =
GMSGFMT = /usr/bin/msgfmt
GREP = /bin/grep
HAVE_GCC_VISIBILITY = 0
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL} $(INSTALL_STRIP_FLAG)
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
KCFG_DEPENDENCIES = $(KCONFIG_COMPILER)
KCONFIG_COMPILER = /usr/bin/kconfig_compiler
KDECONFIG = /usr/bin/kde-config
KDE_CHECK_PLUGIN = $(KDE_PLUGIN) -rpath $(libdir)
KDE_EXTRA_RPATH =
KDE_HAS_DOXYGEN = no
KDE_HAVE_DOT = NO
KDE_INCLUDES = -I/usr/include/kde
KDE_LDFLAGS = -L/usr/lib
KDE_MT_LDFLAGS =
KDE_MT_LIBS = -lpthread
KDE_NO_UNDEFINED = -Wl,--no-undefined -Wl,--allow-shlib-undefined
KDE_PLUGIN = -avoid-version -module -no-undefined $(KDE_NO_UNDEFINED) $(KDE_RPATH) $(KDE_MT_LDFLAGS)
KDE_RPATH = -R $(libdir) -R $(kde_libraries) -R $(qt_libraries)
KDE_USE_CLOSURE_FALSE =
KDE_USE_CLOSURE_TRUE = #
KDE_USE_FINAL_FALSE =
KDE_USE_FINAL_TRUE = #
KDE_USE_FPIE = -fPIE
KDE_USE_NMCHECK_FALSE =
KDE_USE_NMCHECK_TRUE = #
KDE_USE_PIE = -pie
KDE_XSL_STYLESHEET = /usr/share/apps/ksgmltools2/customization/kde-chunk.xsl
LDFLAGS =
LDFLAGS_AS_NEEDED =
LDFLAGS_NEW_DTAGS =
LIBCOMPAT =
LIBCRYPT = -lcrypt
LIBDL = -ldl
LIBJPEG = -ljpeg
LIBOBJS =
LIBPNG = -lpng -lz -lm
LIBPTHREAD = -lpthread
LIBRESOLV = -lresolv
LIBS =
LIBSM = -lSM -lICE
LIBSOCKET =
LIBTOOL = $(SHELL) $(top_builddir)/libtool --silent
LIBUCB =
LIBUTIL = -lutil
LIBZ = -lz
LIB_ARTS =
LIB_DPMS = -lXext
LIB_GSTREAMER =
LIB_KAB = -lkab
LIB_KABC = -lkabc
LIB_KDECORE = -lkdecore
LIB_KDED =
LIB_KDEPIM = -lkdepim
LIB_KDEPRINT = -lkdeprint
LIB_KDEUI = -lkdeui
LIB_KDNSSD = -lkdnssd
LIB_KFILE = -lkio
LIB_KFM =
LIB_KHTML = -lkhtml
LIB_KIMPROXY = -lkimproxy
LIB_KIO = -lkio
LIB_KJS = -lkjs
LIB_KNEWSTUFF = -lknewstuff
LIB_KPARTS = -lkparts
LIB_KSPELL = -lkspell
LIB_KSYCOCA = -lkio
LIB_KUNITTEST = -lkunittest
LIB_KUTILS = -lkutils
LIB_LAME = -lmp3lame
LIB_OGGVORBIS = -lvorbisenc -lvorbis -lm -logg
LIB_POLL =
LIB_QPE =
LIB_QT = -lqt-mt $(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM) -lpthread
LIB_SMB = -lsmb
LIB_X11 = -lX11 $(LIBSOCKET)
LIB_XCB =
LIB_XEXT = -lXext
LIB_XINE = -lxine
LIB_XINERAMA = -lXinerama
LIB_XRENDER =
LIB_XTEST = -lXtst
LN_S = ln -s
LTLIBOBJS =
MAKEINFO = ${SHELL} /partage/Linux/site/tmp/kaffeine-0.8.8/admin/missing --run makeinfo
MAKEKDEWIDGETS = /usr/bin/makekdewidgets
MCOPIDL =
MEINPROC = /usr/bin/meinproc
MOC = /usr/share/qt3/bin/moc
MSGFMT = /usr/bin/msgfmt
NOOPT_CFLAGS = -O0
NOOPT_CXXFLAGS = -O0
OBJEXT = o
PACKAGE = kaffeine-0.8.8
PACKAGE_BUGREPORT =
PACKAGE_NAME =
PACKAGE_STRING =
PACKAGE_TARNAME =
PACKAGE_VERSION =
PATH_SEPARATOR = :
PERL = /usr/bin/perl
PKG_CONFIG = pkg-config
QTDOCDIR = /usr/share/qt3/doc/html
QTE_NORTTI =
QT_INCLUDES = -I/usr/share/qt3/include
QT_LDFLAGS = -L/usr/share/qt3/lib
RANLIB = ranlib
SET_MAKE =
SHELL = /bin/bash
STRIP = strip
TOPSUBDIRS = doc kaffeine po
UIC = /usr/share/qt3/bin/uic -L $(kde_widgetdir) -nounload
UIC_TR = tr2i18n
USER_INCLUDES =
USER_LDFLAGS =
USE_EXCEPTIONS = -fexceptions
USE_RTTI =
USE_THREADS =
VERSION = 3.5.7
WOVERLOADED_VIRTUAL =
XGETTEXT = /usr/bin/xgettext
XMKMF =
XMLLINT = /usr/bin/xmllint
X_EXTRA_LIBS =
X_INCLUDES = -I.
X_LDFLAGS =
X_PRE_LIBS =
X_RPATH =
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_F77 =
all_includes = -I/usr/include/kde -I/usr/share/qt3/include -I.
all_libraries = -L/usr/share/qt3/lib
am__fastdepCC_FALSE = #
am__fastdepCC_TRUE =
am__fastdepCXX_FALSE = #
am__fastdepCXX_TRUE =
am__include = include
am__leading_dot = .
am__quote =
bindir = ${exec_prefix}/bin
build = i686-pc-linux-gnu
build_alias =
build_cpu = i686
build_os = linux-gnu
build_vendor = pc
datadir = ${datarootdir}
datarootdir = ${prefix}/share
doc_SUBDIR_included_FALSE = #
doc_SUBDIR_included_TRUE =
docdir = ${datarootdir}/doc/${PACKAGE}
dvidir = ${docdir}
exec_prefix = ${prefix}
host = i686-pc-linux-gnu
host_alias =
host_cpu = i686
host_os = linux-gnu
host_vendor = pc
htmldir = ${docdir}
include_ARTS_FALSE =
include_ARTS_TRUE = #
include_x11_FALSE = #
include_x11_TRUE =
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = /partage/Linux/site/tmp/kaffeine-0.8.8/admin/install-sh
kaffeine_SUBDIR_included_FALSE = #
kaffeine_SUBDIR_included_TRUE =
kde_appsdir = ${datadir}/applnk
kde_bindir = ${exec_prefix}/bin
kde_confdir = ${datadir}/config
kde_datadir = ${datadir}/apps
kde_htmldir = ${datadir}/doc/HTML
kde_icondir = ${datadir}/icons
kde_includes = /usr/include/kde
kde_kcfgdir = ${datadir}/config.kcfg
kde_libraries = /usr/lib
kde_libs_htmldir = /usr/share/doc/kde/HTML
kde_libs_prefix = /usr
kde_locale = ${datadir}/locale
kde_mimedir = ${datadir}/mimelnk
kde_moduledir = ${libdir}/kde3
kde_qtver = 3
kde_servicesdir = ${datadir}/services
kde_servicetypesdir = ${datadir}/servicetypes
kde_sounddir = ${datadir}/sounds
kde_styledir = ${libdir}/kde3/plugins/styles
kde_templatesdir = ${datadir}/templates
kde_wallpaperdir = ${datadir}/wallpapers
kde_widgetdir = /usr/lib/kde3/plugins/designer
kdeinitdir = $(kde_moduledir)
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
oldincludedir = /usr/include
pdfdir = ${docdir}
po_SUBDIR_included_FALSE = #
po_SUBDIR_included_TRUE =
prefix = /usr
program_transform_name = s,x,x,
psdir = ${docdir}
qt_includes = /usr/share/qt3/include
qt_libraries = /usr/share/qt3/lib
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
sysconfdir = ${prefix}/etc
target = i686-pc-linux-gnu
target_alias =
target_cpu = i686
target_os = linux-gnu
target_vendor = pc
unsermake_enable_pch_FALSE =
unsermake_enable_pch_TRUE = #
with_dvb_FALSE = #
with_dvb_TRUE =
with_gstreamer_FALSE =
with_gstreamer_TRUE = #
with_lame_FALSE = #
with_lame_TRUE =
with_oggvorbis_FALSE = #
with_oggvorbis_TRUE =
with_xcb_FALSE =
with_xcb_TRUE = #
x_includes = .
x_libraries = /usr/lib
xdg_appsdir = ${datadir}/applications/kde
xdg_directorydir = ${datadir}/desktop-directories
xdg_menudir = ${sysconfdir}/xdg/menus
kde_module_LTLIBRARIES = libdummypart.la
INCLUDES = -I$(top_srcdir)/kaffeine/src/player-parts/ $(all_includes)
#>- METASOURCES = AUTO
noinst_HEADERS = dummy_part.h
libdummypart_la_SOURCES = dummy_part.cpp
libdummypart_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE) ../libkaffeinepart.la
#>- libdummypart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -avoid-version -no-undefined
#>+ 1
libdummypart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -avoid-version -no-undefined $(KDE_NO_UNDEFINED)
# this is where the desktop file will go
partdesktopdir = $(kde_servicesdir)
partdesktop_DATA = dummy_part.desktop
# this is where the part's XML-GUI resource file goes
partrcdir = $(kde_datadir)/dummypart
partrc_DATA = dummy_part.rc
subdir = kaffeine/src/player-parts/dummy-part
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(kde_module_LTLIBRARIES)
libdummypart_la_DEPENDENCIES = ../libkaffeinepart.la
am_libdummypart_la_OBJECTS = dummy_part.lo
#>- libdummypart_la_OBJECTS = $(am_libdummypart_la_OBJECTS)
#>+ 5
libdummypart_la_final_OBJECTS = libdummypart_la.all_cpp.lo
libdummypart_la_nofinal_OBJECTS = dummy_part.lo\
dummy_part.moc.lo
libdummypart_la_OBJECTS = $(libdummypart_la_nofinal_OBJECTS)
#libdummypart_la_OBJECTS = $(libdummypart_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- DEP_FILES = ./$(DEPDIR)/dummy_part.Plo
#>+ 2
#DEP_FILES = $(DEPDIR)/dummy_part.moc.P $(DEPDIR)/libdummypart_la.all_cpp.P ./$(DEPDIR)/dummy_part.Plo
DEP_FILES = $(DEPDIR)/dummy_part.moc.P ./$(DEPDIR)/dummy_part.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libdummypart_la_SOURCES)
DATA = $(partdesktop_DATA) $(partrc_DATA)
HEADERS = $(noinst_HEADERS)
DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.in \
Makefile.am
SOURCES = $(libdummypart_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu kaffeine/src/player-parts/dummy-part/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu kaffeine/src/player-parts/dummy-part/Makefile
cd $(top_srcdir) && perl admin/am_edit kaffeine/src/player-parts/dummy-part/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
kde_moduleLTLIBRARIES_INSTALL = $(INSTALL)
install-kde_moduleLTLIBRARIES: $(kde_module_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(kde_moduledir)
@list='$(kde_module_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=install $(kde_moduleLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(kde_moduledir)/$$f"; \
$(LIBTOOL) --mode=install $(kde_moduleLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(kde_moduledir)/$$f; \
else :; fi; \
done
uninstall-kde_moduleLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(kde_module_LTLIBRARIES)'; for p in $$list; do \
p="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(kde_moduledir)/$$p"; \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(kde_moduledir)/$$p; \
done
clean-kde_moduleLTLIBRARIES:
-test -z "$(kde_module_LTLIBRARIES)" || rm -f $(kde_module_LTLIBRARIES)
@list='$(kde_module_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
#>- libdummypart.la: $(libdummypart_la_OBJECTS) $(libdummypart_la_DEPENDENCIES)
#>+ 2
#libdummypart.la: libdummypart.la.closure $(libdummypart_la_OBJECTS) $(libdummypart_la_DEPENDENCIES)
libdummypart.la: $(libdummypart_la_OBJECTS) $(libdummypart_la_DEPENDENCIES)
$(CXXLINK) -rpath $(kde_moduledir) $(libdummypart_la_LDFLAGS) $(libdummypart_la_OBJECTS) $(libdummypart_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/dummy_part.Plo
.cpp.o:
if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
# source='$<' object='$@' libtool=no \
# depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
# $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
# source='$<' object='$@' libtool=no \
# depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
# $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
fi
# source='$<' object='$@' libtool=yes \
# depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' \
# $(CXXDEPMODE) $(depcomp) \
# $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
partdesktopDATA_INSTALL = $(INSTALL_DATA)
install-partdesktopDATA: $(partdesktop_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(partdesktopdir)
@list='$(partdesktop_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(partdesktopDATA_INSTALL) $$d$$p $(DESTDIR)$(partdesktopdir)/$$f"; \
$(partdesktopDATA_INSTALL) $$d$$p $(DESTDIR)$(partdesktopdir)/$$f; \
done
uninstall-partdesktopDATA:
@$(NORMAL_UNINSTALL)
@list='$(partdesktop_DATA)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(partdesktopdir)/$$f"; \
rm -f $(DESTDIR)$(partdesktopdir)/$$f; \
done
partrcDATA_INSTALL = $(INSTALL_DATA)
install-partrcDATA: $(partrc_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(partrcdir)
@list='$(partrc_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(partrcDATA_INSTALL) $$d$$p $(DESTDIR)$(partrcdir)/$$f"; \
$(partrcDATA_INSTALL) $$d$$p $(DESTDIR)$(partrcdir)/$$f; \
done
uninstall-partrcDATA:
@$(NORMAL_UNINSTALL)
@list='$(partrc_DATA)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(partrcdir)/$$f"; \
rm -f $(DESTDIR)$(partrcdir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
#>+ 1
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
top_distdir = ../../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(kde_moduledir) $(DESTDIR)$(partdesktopdir) $(DESTDIR)$(partrcdir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
#>- clean-am: clean-generic clean-kde_moduleLTLIBRARIES clean-libtool \
#>- mostlyclean-am
#>+ 2
clean-am: clean-metasources clean-closures clean-bcheck clean-final clean-generic clean-kde_moduleLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
#>- install-data-am: install-kde_moduleLTLIBRARIES install-partdesktopDATA \
#>- install-partrcDATA
#>+ 2
install-data-am: install-partdesktopDATA \
install-partrcDATA
#>- install-exec-am:
#>+ 1
install-exec-am: install-kde_moduleLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-kde_moduleLTLIBRARIES \
uninstall-partdesktopDATA uninstall-partrcDATA
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-kde_moduleLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am \
install-kde_moduleLTLIBRARIES install-man \
install-partdesktopDATA install-partrcDATA install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-kde_moduleLTLIBRARIES uninstall-partdesktopDATA \
uninstall-partrcDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 8
libdummypart.la.closure: $(libdummypart_la_OBJECTS) $(libdummypart_la_DEPENDENCIES)
@echo "int main() {return 0;}" > libdummypart_la_closure.cpp
@$(LTCXXCOMPILE) -c libdummypart_la_closure.cpp
$(CXXLINK) libdummypart_la_closure.lo $(libdummypart_la_LDFLAGS) $(libdummypart_la_OBJECTS) $(libdummypart_la_LIBADD) $(LIBS)
@rm -f libdummypart_la_closure.* libdummypart.la.closure
@echo "timestamp" > libdummypart.la.closure
#>+ 3
dummy_part.moc.cpp: $(srcdir)/dummy_part.h
$(MOC) $(srcdir)/dummy_part.h -o dummy_part.moc.cpp
#>+ 2
mocs: dummy_part.moc.cpp
#>+ 3
clean-metasources:
-rm -f dummy_part.moc.cpp
#>+ 2
KDE_DIST=dummy_part.desktop Makefile.in dummy_part.rc
#>+ 3
clean-closures:
-rm -f libdummypart.la.closure
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu kaffeine/src/player-parts/dummy-part/Makefile
cd $(top_srcdir) && perl admin/am_edit kaffeine/src/player-parts/dummy-part/Makefile.in
#>+ 21
clean-bcheck:
rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
bcheck: bcheck-am
bcheck-am:
@for i in ; do \
if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
echo "$$i"; \
if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
rm -f $$i.bchecktest.cc; exit 1; \
fi ; \
echo "" >> $$i.bchecktest.cc.class; \
perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
rm -f a.out; \
fi ; \
done
#>+ 11
libdummypart_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/dummy_part.cpp dummy_part.moc.cpp
@echo 'creating libdummypart_la.all_cpp.cpp ...'; \
rm -f libdummypart_la.all_cpp.files libdummypart_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libdummypart_la.all_cpp.final; \
for file in dummy_part.cpp dummy_part.moc.cpp ; do \
echo "#include \"$$file\"" >> libdummypart_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libdummypart_la.all_cpp.final; \
done; \
cat libdummypart_la.all_cpp.final libdummypart_la.all_cpp.files > libdummypart_la.all_cpp.cpp; \
rm -f libdummypart_la.all_cpp.final libdummypart_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libdummypart_la.all_cpp.cpp
#>+ 3
final:
$(MAKE) libdummypart_la_OBJECTS="$(libdummypart_la_final_OBJECTS)" all-am
#>+ 3
final-install:
$(MAKE) libdummypart_la_OBJECTS="$(libdummypart_la_final_OBJECTS)" install-am
#>+ 3
no-final:
$(MAKE) libdummypart_la_OBJECTS="$(libdummypart_la_nofinal_OBJECTS)" all-am
#>+ 3
no-final-install:
$(MAKE) libdummypart_la_OBJECTS="$(libdummypart_la_nofinal_OBJECTS)" install-am
#>+ 3
kde-rpo-clean:
-rm -f *.rpo
#>+ 3
nmcheck:
nmcheck-am: nmcheck

@ -8,7 +8,7 @@ noinst_HEADERS = gstreamer_part.h timer.h video.h videosettings.h gstreamerconf
libgstreamerpart_la_SOURCES = gstreamer_part.cpp video.cpp timer.cpp videosettings.cpp gstreamerconfig.cpp
libgstreamerpart_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE) ../kaffeine-part/libkaffeinepart.la
libgstreamerpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(LIB_QT) -lDCOP $(KDE_PLUGIN) $(LIB_KPARTS) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) $(LIB_GSTREAMER) -lgstinterfaces-0.10 $(all_libraries) -avoid-version -no-undefined
libgstreamerpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(LIB_GSTREAMER) -lgstinterfaces-0.10 $(all_libraries) -avoid-version -no-undefined
# this is where the desktop file will go
partdesktopdir = $(kde_servicesdir)

@ -16,12 +16,15 @@ Comment[cs]=Část přehrávače založená na GStreameru.
Comment[da]=En Kaffeine-grænseflade baseret på Gstreamer.
Comment[de]=Ein auf GStreamer basierendes Programmmodul.
Comment[el]=Μία μηχανή του Kaffeine βασισμένη στο GStreamer.
Comment[es]=Un motor de Kaffeine basado en GStreamer.
Comment[et]=Kaffeine mootor GStreameri põhjal.
Comment[fi]=GStreamer-kirjastoa käyttävä toistoydin.
Comment[ga]=Inneall Kaffeine bunaithe ar GStreamer.
Comment[gl]=Un motor para Kaffeine baseado en GStreamer.
Comment[hu]=GStreamer-alapú Kaffeine-alrendszer.
Comment[it]=Un motore di Kaffeine basato su GStreamer.
Comment[ja]=GStreamer に基づく Kaffeine エンジン
Comment[km]=ម៉ាស៊ីន​ Kaffeine មាន​មូលដ្ឋាន​លើ GStreamer 
Comment[lt]=Kaffeine variklis, paremtas GStreamer.
Comment[nb]=En spillermotor basert på GStreamer.
Comment[nl]=Een Kaffeine-engine gebaseerd op GStreamer.
@ -38,7 +41,7 @@ Comment[th]=โปรแกรมประมวลผลของ Kaffeine โ
Comment[tr]=GStreamer tabanlı bir Kaffeine motoru.
Comment[uk]=Рушій Kaffeine, оснований на GStreamer.
Comment[xx]=xxA Kaffeine engine based on GStreamer.xx
MimeType=application/x-ogg;video/x-matroska;audio/x-matroska;video/mpeg;video/msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-avi;video/x-fli;video/x-flic;video/x-ms-asf;video/x-ms-wmv;video/x-msvideo;application/x-mplayer2;application/smil;application/x-kaffeine;audio/x-musepack;
MimeType=application/x-ogg;audio/basic;audio/vnd.rn-realaudio;audio/x-aiff;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-ogg;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;audio/x-scpls;audio/x-wav;audio/x-flac;video/x-matroska;audio/x-matroska;video/mpeg;video/msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-avi;video/x-fli;video/x-flic;video/x-ms-asf;video/x-ms-wmv;video/x-msvideo;application/x-mplayer2;application/smil;application/x-kaffeine;audio/x-musepack;
ServiceTypes=KParts/ReadOnlyPart,KaffeinePart
Type=Service
X-KDE-Library=libgstreamerpart

@ -19,12 +19,6 @@
*/
#include "kaffeinepart.h"
#include <kapplication.h>
#include <kservice.h>
#include <ktrader.h>
#include <kmessagebox.h>
#include <krun.h>
#include <klocale.h>
#include "kaffeinepart.moc"
@ -36,23 +30,3 @@ KaffeinePart::KaffeinePart(QObject* parent, const char* name)
KaffeinePart::~KaffeinePart()
{
}
bool KaffeinePart::installDistroCodec(QWidget* parent, const QString& engine, const QString& codec)
{
QString query = QString("[X-KDE-Kaffeine-codec] == '%1' and \
[X-KDE-Kaffeine-engine] == '%2'").arg(codec).arg(engine);
KService::Ptr service = KTrader::self()->query( "Kaffeine/CodecInstall", query).first();
if (!service)
return false;
QString installScript = service->exec();
if (installScript.isNull())
return false;
KRun::runCommand(installScript);
return true;
}

@ -199,11 +199,6 @@ public slots:
virtual void slotMute()
{}
/*
* Execute distro-dependent actions to install codecs
*/
static bool installDistroCodec(QWidget* parent, const QString& engine, const QString& codec);
private:
/*
* Don't reimplement this, a player should be able to stream media

@ -14,7 +14,7 @@ libxinepart_la_SOURCES = xine_part.cpp kxinewidget.cpp postfilter.cpp deinterlac
videosettings.cpp filterdialog.cpp screenshotpreview.cpp xineconfig.cpp positionslider.cpp \
equalizer.cpp xine_part_iface.skel
libxinepart_la_LIBADD = $(LIB_XINERAMA) $(LIB_XINE) $(LIB_XCB) ../kaffeine-part/libkaffeinepart.la
libxinepart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) $(LIB_QT) -lDCOP $(KDE_PLUGIN) $(LIB_KPARTS) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) $(LIB_KDEPRINT) -avoid-version -no-undefined
libxinepart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -avoid-version -no-undefined
# this is where the desktop file will go

@ -36,7 +36,6 @@
#include <cmath>
#include "kxinewidget.h"
#include "kaffeinepart.h"
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
@ -636,8 +635,7 @@ void KXineWidget::xineEventListener(void *p, const xine_event_t* xineEvent)
message = i18n("The source can't be read.\nMaybe you don't have enough rights for this, or source doesn't contain data (e.g: no disc in drive). ");
if(data->explanation)
message = message + "(" + ((char *) data + data->parameters) + ")";
debugOut(message);
return; // This error is handled by autoinstallation
break;
}
case XINE_MSG_LIBRARY_LOAD_ERROR:
{
@ -650,11 +648,7 @@ void KXineWidget::xineEventListener(void *p, const xine_event_t* xineEvent)
{
message = i18n("The source seems encrypted, and can't be read. ");
if (vw->m_trackURL.contains("dvd:/"))
{
if (KaffeinePart::installDistroCodec(vw, "xine-engine", "dvdcss"))
return;
message = message + i18n("\nYour DVD is probably crypted. According to your country laws, you can or can't use libdvdcss to be able to read this disc. ");
}
if(data->explanation)
message = message + "(" + ((char *) data + data->parameters) + ")";
break;
@ -1683,7 +1677,7 @@ void KXineWidget::dvbShowOSD()
int h = m_videoFrameHeight;
if ( !w || !h )
return;
if ( w<800 ) {
if ( w<1921 ) {
if ( dvbCurrentNext[0]=="E" ) {
dvbOSDHideTimer.stop();
dvbOSD = xine_osd_new( m_xineStream, border, border, w-(2*border), h-(2/border) );
@ -1864,7 +1858,7 @@ void KXineWidget::setDvbCurrentNext( const QString &channelName, const QStringLi
void KXineWidget::setDvb( const QString &pipeName, const QString &chanName, int haveVideo )
{
m_trackURL = pipeName;
m_trackURL = /*"fifo://"+*/pipeName;
m_trackTitle = chanName;
dvbHaveVideo = haveVideo;
}
@ -1916,15 +1910,6 @@ void KXineWidget::slotPlayTimeShift()
m_posTimer.start(1000);
}
bool KXineWidget::unhandledStreamsPresent()
{
unsigned int hasAudio = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_AUDIO);
unsigned int hasVideo = xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_HAS_VIDEO);
return (hasAudio && !xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_AUDIO_HANDLED)) ||
(hasVideo && !xine_get_stream_info(m_xineStream, XINE_STREAM_INFO_VIDEO_HANDLED));
}
void KXineWidget::slotPlay()
{
if ((!isXineReady()) || (isQueueEmpty()))
@ -2007,13 +1992,6 @@ void KXineWidget::slotPlay()
return;
}
if (unhandledStreamsPresent())
{
errorOut("No codecs to handle media");
sendXineError();
return;
}
/**** use visualization ? ****/
#ifndef USE_QT_ONLY
unwireAudioFilters();
@ -2232,17 +2210,6 @@ void KXineWidget::sendXineError()
case XINE_ERROR_NO_INPUT_PLUGIN:
case XINE_ERROR_NO_DEMUX_PLUGIN:
{
if (m_trackURL.startsWith("dvd:/"))
{
if (KaffeinePart::installDistroCodec(this, "xine-engine", "dvdcss"))
return;
}
else
{
if (KaffeinePart::installDistroCodec(this, "xine-engine", "ffmpeg"))
return;
}
error = i18n("No plugin found to handle this resource") + " " + addInfo;
break;
}
@ -2263,9 +2230,6 @@ void KXineWidget::sendXineError()
}
default:
{
if (unhandledStreamsPresent() && KaffeinePart::installDistroCodec(this, "xine-engine", "ffmpeg"))
return;
error = i18n("Generic error") + " (" + m_trackURL + ")";
break;
}
@ -2895,7 +2859,13 @@ void KXineWidget::slotStop()
if ( m_lengthInfoTimer.isActive() ) m_lengthInfoTimer.stop();
//emit signalNewPosition(0, QTime());
xine_stop(m_xineStream);
if ((m_logoFile.isNull()) && (isPlaying()))
xine_stop(m_xineStream);
else
{
appendToQueue(m_logoFile);
QTimer::singleShot(0, this, SLOT(slotPlay()));
}
emit signalXineStatus(i18n("Stop"));
}

@ -321,7 +321,6 @@ private:
#else
void paintEvent(QPaintEvent *);
#endif
bool unhandledStreamsPresent();
/********* callbacks and threads ************/
static void destSizeCallback(void* p, int video_width, int video_height, double video_aspect,

@ -1,7 +1,7 @@
[Desktop Entry]
Encoding=UTF-8
Icon=kaffeine
MimeType=application/x-ogg;video/x-matroska;audio/x-matroska;video/mpeg;video/msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-avi;video/x-fli;video/x-flic;video/x-ms-asf;video/x-ms-wmv;video/x-msvideo;application/x-mplayer2;application/smil;application/x-kaffeine;audio/x-musepack;
MimeType=application/x-ogg;audio/basic;audio/vnd.rn-realaudio;audio/x-aiff;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-ogg;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;audio/x-scpls;audio/x-wav;audio/x-flac;video/x-matroska;audio/x-matroska;video/mpeg;video/msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-avi;video/x-fli;video/x-flic;video/x-ms-asf;video/x-ms-asf-plugin;video/x-ms-wmv;video/x-msvideo;application/x-mplayer2;application/smil;application/x-kaffeine;audio/x-musepack;
Name=Kaffeine-Xine
Name[nb]=Kaffeine Xine
Name[pa]=ਕੈਫੀਨ-ਜ਼ਾਇਨ
@ -15,12 +15,15 @@ Comment[cs]=Část přehrávače založená na xine.
Comment[da]=En Kaffeine-grænseflade baseret på Xine.
Comment[de]=Ein auf Xine basierendes Programmmodul.
Comment[el]=Μία μηχανή του Kaffeine βασισμένη στο xine.
Comment[es]=Un motor de Kaffeine basado en xine.
Comment[et]=Kaffeine mootor xine põhjal.
Comment[fi]=xine-kirjastoa käyttävä toistoydin.
Comment[ga]=Inneall Kaffeine bunaithe ar xine.
Comment[gl]=Un motor para Kaffeine baseado en Xine.
Comment[hu]=Xine-alapú Kaffeine-alrendszer.
Comment[it]=Un motore di Kaffeine basato su xine.
Comment[ja]=xine に基づく Kaffeine エンジン
Comment[km]=ម៉ាស៊ីន​ Kaffeine មាន​មូលដ្ឋាន​លើ xine 
Comment[lt]=Kaffeine variklis, paremtas Xine.
Comment[nb]=En spillermotor basert på xine.
Comment[nl]=Een Kaffeine-engine gebaseerd op xine.

@ -1 +1 @@
#define KAFFEINE_VERSION "0.8.6"
#define KAFFEINE_VERSION "0.8.8"

Loading…
Cancel
Save