2004-01-11 15:54:37 +01:00
/*
* nit . c : NIT section filter
*
* See the main source file ' vdr . c ' for copyright information and
* how to reach the author .
*
2011-08-12 14:37:25 +02:00
* $ Id : nit . c 2.6 2011 / 08 / 12 14 : 27 : 31 kls Exp $
2004-01-11 15:54:37 +01:00
*/
# include "nit.h"
# include <linux/dvb/frontend.h>
# include "channels.h"
2010-02-28 12:19:50 +01:00
# include "dvbdevice.h"
2004-01-11 15:54:37 +01:00
# include "eitscan.h"
# include "libsi/section.h"
# include "libsi/descriptor.h"
# include "tools.h"
cNitFilter : : cNitFilter ( void )
{
2004-01-18 16:31:58 +01:00
numNits = 0 ;
networkId = 0 ;
2004-01-11 15:54:37 +01:00
Set ( 0x10 , 0x40 ) ; // NIT
}
void cNitFilter : : SetStatus ( bool On )
{
cFilter : : SetStatus ( On ) ;
2004-01-18 16:31:58 +01:00
numNits = 0 ;
networkId = 0 ;
2004-01-11 15:54:37 +01:00
sectionSyncer . Reset ( ) ;
}
void cNitFilter : : Process ( u_short Pid , u_char Tid , const u_char * Data , int Length )
{
SI : : NIT nit ( Data , false ) ;
if ( ! nit . CheckCRCAndParse ( ) )
return ;
2004-01-18 16:31:58 +01:00
// Some broadcasters send more than one NIT, with no apparent way of telling which
// one is the right one to use. This is an attempt to find the NIT that contains
// the transponder it was transmitted on and use only that one:
int ThisNIT = - 1 ;
if ( ! networkId ) {
for ( int i = 0 ; i < numNits ; i + + ) {
if ( nits [ i ] . networkId = = nit . getNetworkId ( ) ) {
if ( nit . getSectionNumber ( ) = = 0 ) {
// all NITs have passed by
for ( int j = 0 ; j < numNits ; j + + ) {
if ( nits [ j ] . hasTransponder ) {
networkId = nits [ j ] . networkId ;
//printf("taking NIT with network ID %d\n", networkId);
2006-05-27 15:35:16 +02:00
//XXX what if more than one NIT contains this transponder???
2004-01-18 16:31:58 +01:00
break ;
}
}
if ( ! networkId ) {
//printf("none of the NITs contains transponder %d\n", Transponder());
return ;
}
}
else {
ThisNIT = i ;
break ;
}
}
}
if ( ! networkId & & ThisNIT < 0 & & numNits < MAXNITS ) {
if ( nit . getSectionNumber ( ) = = 0 ) {
* nits [ numNits ] . name = 0 ;
SI : : Descriptor * d ;
for ( SI : : Loop : : Iterator it ; ( d = nit . commonDescriptors . getNext ( it ) ) ; ) {
switch ( d - > getDescriptorTag ( ) ) {
case SI : : NetworkNameDescriptorTag : {
SI : : NetworkNameDescriptor * nnd = ( SI : : NetworkNameDescriptor * ) d ;
2004-06-06 14:53:21 +02:00
nnd - > name . getText ( nits [ numNits ] . name , MAXNETWORKNAME ) ;
2004-01-18 16:31:58 +01:00
}
break ;
default : ;
}
2004-05-22 15:47:06 +02:00
delete d ;
2004-01-18 16:31:58 +01:00
}
nits [ numNits ] . networkId = nit . getNetworkId ( ) ;
nits [ numNits ] . hasTransponder = false ;
//printf("NIT[%d] %5d '%s'\n", numNits, nits[numNits].networkId, nits[numNits].name);
ThisNIT = numNits ;
numNits + + ;
}
}
}
else if ( networkId ! = nit . getNetworkId ( ) )
return ; // ignore all other NITs
else if ( ! sectionSyncer . Sync ( nit . getVersionNumber ( ) , nit . getSectionNumber ( ) , nit . getLastSectionNumber ( ) ) )
2004-01-11 15:54:37 +01:00
return ;
if ( ! Channels . Lock ( true , 10 ) )
return ;
2004-10-16 10:14:19 +02:00
SI : : NIT : : TransportStream ts ;
for ( SI : : Loop : : Iterator it ; nit . transportStreamLoop . getNext ( ts , it ) ; ) {
2004-01-11 15:54:37 +01:00
SI : : Descriptor * d ;
2006-05-27 15:35:16 +02:00
SI : : Loop : : Iterator it2 ;
SI : : FrequencyListDescriptor * fld = ( SI : : FrequencyListDescriptor * ) ts . transportStreamDescriptors . getNext ( it2 , SI : : FrequencyListDescriptorTag ) ;
int NumFrequencies = fld ? fld - > frequencies . getCount ( ) + 1 : 1 ;
int Frequencies [ NumFrequencies ] ;
if ( fld ) {
int ct = fld - > getCodingType ( ) ;
if ( ct > 0 ) {
int n = 1 ;
for ( SI : : Loop : : Iterator it3 ; fld - > frequencies . hasNext ( it3 ) ; ) {
int f = fld - > frequencies . getNext ( it3 ) ;
switch ( ct ) {
case 1 : f = BCD2INT ( f ) / 100 ; break ;
case 2 : f = BCD2INT ( f ) / 10 ; break ;
case 3 : f = f * 10 ; break ;
2009-12-06 12:57:45 +01:00
default : ;
2006-05-27 15:35:16 +02:00
}
Frequencies [ n + + ] = f ;
}
}
else
NumFrequencies = 1 ;
}
delete fld ;
2004-01-11 15:54:37 +01:00
for ( SI : : Loop : : Iterator it2 ; ( d = ts . transportStreamDescriptors . getNext ( it2 ) ) ; ) {
switch ( d - > getDescriptorTag ( ) ) {
case SI : : SatelliteDeliverySystemDescriptorTag : {
SI : : SatelliteDeliverySystemDescriptor * sd = ( SI : : SatelliteDeliverySystemDescriptor * ) d ;
2010-02-28 12:19:50 +01:00
cDvbTransponderParameters dtp ;
2004-01-11 15:54:37 +01:00
int Source = cSource : : FromData ( cSource : : stSat , BCD2INT ( sd - > getOrbitalPosition ( ) ) , sd - > getWestEastFlag ( ) ) ;
2006-05-27 15:35:16 +02:00
int Frequency = Frequencies [ 0 ] = BCD2INT ( sd - > getFrequency ( ) ) / 100 ;
2010-02-28 12:19:50 +01:00
static char Polarizations [ ] = { ' H ' , ' V ' , ' L ' , ' R ' } ;
dtp . SetPolarization ( Polarizations [ sd - > getPolarization ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int CodeRates [ ] = { FEC_NONE , FEC_1_2 , FEC_2_3 , FEC_3_4 , FEC_5_6 , FEC_7_8 , FEC_8_9 , FEC_3_5 , FEC_4_5 , FEC_9_10 , FEC_AUTO , FEC_AUTO , FEC_AUTO , FEC_AUTO , FEC_AUTO , FEC_NONE } ;
2010-02-28 12:19:50 +01:00
dtp . SetCoderateH ( CodeRates [ sd - > getFecInner ( ) ] ) ;
2008-12-20 11:05:22 +01:00
static int Modulations [ ] = { QAM_AUTO , QPSK , PSK_8 , QAM_16 } ;
2010-02-28 12:19:50 +01:00
dtp . SetModulation ( Modulations [ sd - > getModulationType ( ) ] ) ;
dtp . SetSystem ( sd - > getModulationSystem ( ) ? SYS_DVBS2 : SYS_DVBS ) ;
2008-12-13 12:22:36 +01:00
static int RollOffs [ ] = { ROLLOFF_35 , ROLLOFF_25 , ROLLOFF_20 , ROLLOFF_AUTO } ;
2010-02-28 12:19:50 +01:00
dtp . SetRollOff ( sd - > getModulationSystem ( ) ? RollOffs [ sd - > getRollOff ( ) ] : ROLLOFF_AUTO ) ;
2004-01-11 15:54:37 +01:00
int SymbolRate = BCD2INT ( sd - > getSymbolRate ( ) ) / 10 ;
2004-01-18 16:31:58 +01:00
if ( ThisNIT > = 0 ) {
2006-05-27 15:35:16 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
2010-02-28 12:19:50 +01:00
if ( ISTRANSPONDER ( cChannel : : Transponder ( Frequencies [ n ] , dtp . Polarization ( ) ) , Transponder ( ) ) ) {
2006-05-27 15:35:16 +02:00
nits [ ThisNIT ] . hasTransponder = true ;
//printf("has transponder %d\n", Transponder());
break ;
}
}
2004-01-18 16:31:58 +01:00
break ;
}
2007-08-17 14:06:09 +02:00
if ( Setup . UpdateChannels > = 5 ) {
bool found = false ;
2011-08-12 14:37:25 +02:00
bool forceTransponderUpdate = false ;
2007-08-17 14:06:09 +02:00
for ( cChannel * Channel = Channels . First ( ) ; Channel ; Channel = Channels . Next ( Channel ) ) {
if ( ! Channel - > GroupSep ( ) & & Channel - > Source ( ) = = Source & & Channel - > Nid ( ) = = ts . getOriginalNetworkId ( ) & & Channel - > Tid ( ) = = ts . getTransportStreamId ( ) ) {
int transponder = Channel - > Transponder ( ) ;
2008-01-25 14:55:39 +01:00
found = true ;
2010-02-28 12:19:50 +01:00
if ( ! ISTRANSPONDER ( cChannel : : Transponder ( Frequency , dtp . Polarization ( ) ) , transponder ) ) {
2007-04-29 11:40:31 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
2010-02-28 12:19:50 +01:00
if ( ISTRANSPONDER ( cChannel : : Transponder ( Frequencies [ n ] , dtp . Polarization ( ) ) , transponder ) ) {
2007-04-29 11:40:31 +02:00
Frequency = Frequencies [ n ] ;
break ;
2006-05-27 15:35:16 +02:00
}
2007-04-29 11:40:31 +02:00
}
2006-05-27 15:35:16 +02:00
}
2010-02-28 12:19:50 +01:00
if ( ISTRANSPONDER ( cChannel : : Transponder ( Frequency , dtp . Polarization ( ) ) , Transponder ( ) ) ) // only modify channels if we're actually receiving this transponder
Channel - > SetTransponderData ( Source , Frequency , SymbolRate , dtp . ToString ( ' S ' ) ) ;
2011-08-12 14:37:25 +02:00
else if ( Channel - > Srate ( ) ! = SymbolRate | | strcmp ( Channel - > Parameters ( ) , dtp . ToString ( ' S ' ) ) )
forceTransponderUpdate = true ; // get us receiving this transponder
2006-05-27 15:35:16 +02:00
}
2004-01-11 15:54:37 +01:00
}
2011-08-12 14:37:25 +02:00
if ( ! found | | forceTransponderUpdate ) {
2007-08-17 14:06:09 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
cChannel * Channel = new cChannel ;
Channel - > SetId ( ts . getOriginalNetworkId ( ) , ts . getTransportStreamId ( ) , 0 , 0 ) ;
2010-02-28 12:19:50 +01:00
if ( Channel - > SetTransponderData ( Source , Frequencies [ n ] , SymbolRate , dtp . ToString ( ' S ' ) ) )
2007-08-17 14:06:09 +02:00
EITScanner . AddTransponder ( Channel ) ;
else
delete Channel ;
}
}
2004-01-11 15:54:37 +01:00
}
}
break ;
case SI : : CableDeliverySystemDescriptorTag : {
SI : : CableDeliverySystemDescriptor * sd = ( SI : : CableDeliverySystemDescriptor * ) d ;
2010-02-28 12:19:50 +01:00
cDvbTransponderParameters dtp ;
2004-01-11 15:54:37 +01:00
int Source = cSource : : FromData ( cSource : : stCable ) ;
2006-05-27 15:35:16 +02:00
int Frequency = Frequencies [ 0 ] = BCD2INT ( sd - > getFrequency ( ) ) / 10 ;
2004-01-11 15:54:37 +01:00
//XXX FEC_outer???
2008-12-13 12:22:36 +01:00
static int CodeRates [ ] = { FEC_NONE , FEC_1_2 , FEC_2_3 , FEC_3_4 , FEC_5_6 , FEC_7_8 , FEC_8_9 , FEC_3_5 , FEC_4_5 , FEC_9_10 , FEC_AUTO , FEC_AUTO , FEC_AUTO , FEC_AUTO , FEC_AUTO , FEC_NONE } ;
2010-02-28 12:19:50 +01:00
dtp . SetCoderateH ( CodeRates [ sd - > getFecInner ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int Modulations [ ] = { QPSK , QAM_16 , QAM_32 , QAM_64 , QAM_128 , QAM_256 , QAM_AUTO } ;
2010-02-28 12:19:50 +01:00
dtp . SetModulation ( Modulations [ min ( sd - > getModulation ( ) , 6 ) ] ) ;
2004-01-11 15:54:37 +01:00
int SymbolRate = BCD2INT ( sd - > getSymbolRate ( ) ) / 10 ;
2004-01-18 16:31:58 +01:00
if ( ThisNIT > = 0 ) {
2006-05-27 15:35:16 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
if ( ISTRANSPONDER ( Frequencies [ n ] / 1000 , Transponder ( ) ) ) {
nits [ ThisNIT ] . hasTransponder = true ;
//printf("has transponder %d\n", Transponder());
break ;
}
}
2004-01-18 16:31:58 +01:00
break ;
}
2007-08-17 14:06:09 +02:00
if ( Setup . UpdateChannels > = 5 ) {
bool found = false ;
2011-08-12 14:37:25 +02:00
bool forceTransponderUpdate = false ;
2007-08-17 14:06:09 +02:00
for ( cChannel * Channel = Channels . First ( ) ; Channel ; Channel = Channels . Next ( Channel ) ) {
if ( ! Channel - > GroupSep ( ) & & Channel - > Source ( ) = = Source & & Channel - > Nid ( ) = = ts . getOriginalNetworkId ( ) & & Channel - > Tid ( ) = = ts . getTransportStreamId ( ) ) {
int transponder = Channel - > Transponder ( ) ;
2008-01-25 14:55:39 +01:00
found = true ;
2007-08-17 14:06:09 +02:00
if ( ! ISTRANSPONDER ( Frequency / 1000 , transponder ) ) {
2007-04-29 11:40:31 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
2007-08-17 14:06:09 +02:00
if ( ISTRANSPONDER ( Frequencies [ n ] / 1000 , transponder ) ) {
2007-04-29 11:40:31 +02:00
Frequency = Frequencies [ n ] ;
break ;
2006-05-27 15:35:16 +02:00
}
2007-04-29 11:40:31 +02:00
}
2006-05-27 15:35:16 +02:00
}
2007-04-29 11:40:31 +02:00
if ( ISTRANSPONDER ( Frequency / 1000 , Transponder ( ) ) ) // only modify channels if we're actually receiving this transponder
2010-02-28 12:19:50 +01:00
Channel - > SetTransponderData ( Source , Frequency , SymbolRate , dtp . ToString ( ' C ' ) ) ;
2011-08-12 14:37:25 +02:00
else if ( Channel - > Srate ( ) ! = SymbolRate | | strcmp ( Channel - > Parameters ( ) , dtp . ToString ( ' C ' ) ) )
forceTransponderUpdate = true ; // get us receiving this transponder
2006-05-27 15:35:16 +02:00
}
2004-01-11 15:54:37 +01:00
}
2011-08-12 14:37:25 +02:00
if ( ! found | | forceTransponderUpdate ) {
2007-08-17 14:06:09 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
cChannel * Channel = new cChannel ;
Channel - > SetId ( ts . getOriginalNetworkId ( ) , ts . getTransportStreamId ( ) , 0 , 0 ) ;
2010-02-28 12:19:50 +01:00
if ( Channel - > SetTransponderData ( Source , Frequencies [ n ] , SymbolRate , dtp . ToString ( ' C ' ) ) )
2007-08-17 14:06:09 +02:00
EITScanner . AddTransponder ( Channel ) ;
else
delete Channel ;
}
}
2004-01-11 15:54:37 +01:00
}
}
break ;
case SI : : TerrestrialDeliverySystemDescriptorTag : {
SI : : TerrestrialDeliverySystemDescriptor * sd = ( SI : : TerrestrialDeliverySystemDescriptor * ) d ;
2010-02-28 12:19:50 +01:00
cDvbTransponderParameters dtp ;
2004-01-18 16:34:25 +01:00
int Source = cSource : : FromData ( cSource : : stTerr ) ;
2006-05-27 15:35:16 +02:00
int Frequency = Frequencies [ 0 ] = sd - > getFrequency ( ) * 10 ;
2008-12-13 12:22:36 +01:00
static int Bandwidths [ ] = { 8000000 , 7000000 , 6000000 , 0 , 0 , 0 , 0 , 0 } ;
2010-02-28 12:19:50 +01:00
dtp . SetBandwidth ( Bandwidths [ sd - > getBandwidth ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int Constellations [ ] = { QPSK , QAM_16 , QAM_64 , QAM_AUTO } ;
2010-02-28 12:19:50 +01:00
dtp . SetModulation ( Constellations [ sd - > getConstellation ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int Hierarchies [ ] = { HIERARCHY_NONE , HIERARCHY_1 , HIERARCHY_2 , HIERARCHY_4 , HIERARCHY_AUTO , HIERARCHY_AUTO , HIERARCHY_AUTO , HIERARCHY_AUTO } ;
2010-02-28 12:19:50 +01:00
dtp . SetHierarchy ( Hierarchies [ sd - > getHierarchy ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int CodeRates [ ] = { FEC_1_2 , FEC_2_3 , FEC_3_4 , FEC_5_6 , FEC_7_8 , FEC_AUTO , FEC_AUTO , FEC_AUTO } ;
2010-02-28 12:19:50 +01:00
dtp . SetCoderateH ( CodeRates [ sd - > getCodeRateHP ( ) ] ) ;
dtp . SetCoderateL ( CodeRates [ sd - > getCodeRateLP ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int GuardIntervals [ ] = { GUARD_INTERVAL_1_32 , GUARD_INTERVAL_1_16 , GUARD_INTERVAL_1_8 , GUARD_INTERVAL_1_4 } ;
2010-02-28 12:19:50 +01:00
dtp . SetGuard ( GuardIntervals [ sd - > getGuardInterval ( ) ] ) ;
2008-12-13 12:22:36 +01:00
static int TransmissionModes [ ] = { TRANSMISSION_MODE_2K , TRANSMISSION_MODE_8K , TRANSMISSION_MODE_AUTO , TRANSMISSION_MODE_AUTO } ;
2010-02-28 12:19:50 +01:00
dtp . SetTransmission ( TransmissionModes [ sd - > getTransmissionMode ( ) ] ) ;
2004-01-18 16:31:58 +01:00
if ( ThisNIT > = 0 ) {
2006-05-27 15:35:16 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
if ( ISTRANSPONDER ( Frequencies [ n ] / 1000000 , Transponder ( ) ) ) {
nits [ ThisNIT ] . hasTransponder = true ;
//printf("has transponder %d\n", Transponder());
break ;
}
}
2004-01-18 16:31:58 +01:00
break ;
}
2007-08-17 14:06:09 +02:00
if ( Setup . UpdateChannels > = 5 ) {
bool found = false ;
2011-08-12 14:37:25 +02:00
bool forceTransponderUpdate = false ;
2007-08-17 14:06:09 +02:00
for ( cChannel * Channel = Channels . First ( ) ; Channel ; Channel = Channels . Next ( Channel ) ) {
if ( ! Channel - > GroupSep ( ) & & Channel - > Source ( ) = = Source & & Channel - > Nid ( ) = = ts . getOriginalNetworkId ( ) & & Channel - > Tid ( ) = = ts . getTransportStreamId ( ) ) {
int transponder = Channel - > Transponder ( ) ;
2008-01-25 14:55:39 +01:00
found = true ;
2007-08-17 14:06:09 +02:00
if ( ! ISTRANSPONDER ( Frequency / 1000000 , transponder ) ) {
2007-04-29 11:40:31 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
2007-08-17 14:06:09 +02:00
if ( ISTRANSPONDER ( Frequencies [ n ] / 1000000 , transponder ) ) {
2007-04-29 11:40:31 +02:00
Frequency = Frequencies [ n ] ;
break ;
2006-05-27 15:35:16 +02:00
}
2007-04-29 11:40:31 +02:00
}
2006-05-27 15:35:16 +02:00
}
2007-04-29 11:40:31 +02:00
if ( ISTRANSPONDER ( Frequency / 1000000 , Transponder ( ) ) ) // only modify channels if we're actually receiving this transponder
2010-02-28 12:19:50 +01:00
Channel - > SetTransponderData ( Source , Frequency , 0 , dtp . ToString ( ' T ' ) ) ;
2011-08-12 14:37:25 +02:00
else if ( strcmp ( Channel - > Parameters ( ) , dtp . ToString ( ' T ' ) ) )
forceTransponderUpdate = true ; // get us receiving this transponder
2006-05-27 15:35:16 +02:00
}
2004-01-11 15:54:37 +01:00
}
2011-08-12 14:37:25 +02:00
if ( ! found | | forceTransponderUpdate ) {
2007-08-17 14:06:09 +02:00
for ( int n = 0 ; n < NumFrequencies ; n + + ) {
cChannel * Channel = new cChannel ;
Channel - > SetId ( ts . getOriginalNetworkId ( ) , ts . getTransportStreamId ( ) , 0 , 0 ) ;
2010-02-28 12:19:50 +01:00
if ( Channel - > SetTransponderData ( Source , Frequencies [ n ] , 0 , dtp . ToString ( ' T ' ) ) )
2007-08-17 14:06:09 +02:00
EITScanner . AddTransponder ( Channel ) ;
else
delete Channel ;
}
2006-05-27 15:35:16 +02:00
}
2004-01-11 15:54:37 +01:00
}
}
break ;
default : ;
}
delete d ;
}
}
Channels . Unlock ( ) ;
}