2002-10-06 10:25:42 +02:00
/*
* channels . c : Channel handling
*
* See the main source file ' vdr . c ' for copyright information and
* how to reach the author .
*
2004-01-11 15:54:37 +01:00
* $ Id : channels . c 1.19 2004 / 01 / 11 15 : 52 : 32 kls Exp $
2002-10-06 10:25:42 +02:00
*/
# include "channels.h"
# include <linux/dvb/frontend.h>
# include <ctype.h>
// IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
// format characters in order to allow any number of blanks after a numeric
// value!
// -- Channel Parameter Maps -------------------------------------------------
const tChannelParameterMap InversionValues [ ] = {
{ 0 , INVERSION_OFF } ,
{ 1 , INVERSION_ON } ,
{ 999 , INVERSION_AUTO } ,
{ - 1 }
} ;
const tChannelParameterMap BandwidthValues [ ] = {
{ 6 , BANDWIDTH_6_MHZ } ,
{ 7 , BANDWIDTH_7_MHZ } ,
{ 8 , BANDWIDTH_8_MHZ } ,
{ 999 , BANDWIDTH_AUTO } ,
{ - 1 }
} ;
const tChannelParameterMap CoderateValues [ ] = {
{ 0 , FEC_NONE } ,
{ 12 , FEC_1_2 } ,
{ 23 , FEC_2_3 } ,
{ 34 , FEC_3_4 } ,
{ 45 , FEC_4_5 } ,
{ 56 , FEC_5_6 } ,
{ 67 , FEC_6_7 } ,
{ 78 , FEC_7_8 } ,
{ 89 , FEC_8_9 } ,
{ 999 , FEC_AUTO } ,
{ - 1 }
} ;
const tChannelParameterMap ModulationValues [ ] = {
{ 0 , QPSK } ,
{ 16 , QAM_16 } ,
{ 32 , QAM_32 } ,
{ 64 , QAM_64 } ,
{ 128 , QAM_128 } ,
{ 256 , QAM_256 } ,
{ 999 , QAM_AUTO } ,
{ - 1 }
} ;
const tChannelParameterMap TransmissionValues [ ] = {
{ 2 , TRANSMISSION_MODE_2K } ,
{ 8 , TRANSMISSION_MODE_8K } ,
{ 999 , TRANSMISSION_MODE_AUTO } ,
{ - 1 }
} ;
const tChannelParameterMap GuardValues [ ] = {
{ 4 , GUARD_INTERVAL_1_4 } ,
{ 8 , GUARD_INTERVAL_1_8 } ,
{ 16 , GUARD_INTERVAL_1_16 } ,
{ 32 , GUARD_INTERVAL_1_32 } ,
{ 999 , GUARD_INTERVAL_AUTO } ,
{ - 1 }
} ;
const tChannelParameterMap HierarchyValues [ ] = {
{ 0 , HIERARCHY_NONE } ,
{ 1 , HIERARCHY_1 } ,
{ 2 , HIERARCHY_2 } ,
{ 4 , HIERARCHY_4 } ,
{ 999 , HIERARCHY_AUTO } ,
{ - 1 }
} ;
int UserIndex ( int Value , const tChannelParameterMap * Map )
{
const tChannelParameterMap * map = Map ;
while ( map & & map - > userValue ! = - 1 ) {
if ( map - > userValue = = Value )
return map - Map ;
map + + ;
}
return - 1 ;
}
int DriverIndex ( int Value , const tChannelParameterMap * Map )
{
const tChannelParameterMap * map = Map ;
while ( map & & map - > userValue ! = - 1 ) {
if ( map - > driverValue = = Value )
return map - Map ;
map + + ;
}
return - 1 ;
}
int MapToUser ( int Value , const tChannelParameterMap * Map )
{
int n = DriverIndex ( Value , Map ) ;
if ( n > = 0 )
return Map [ n ] . userValue ;
return - 1 ;
}
int MapToDriver ( int Value , const tChannelParameterMap * Map )
{
int n = UserIndex ( Value , Map ) ;
if ( n > = 0 )
return Map [ n ] . driverValue ;
return - 1 ;
}
2002-11-24 14:48:38 +01:00
// -- tChannelID -------------------------------------------------------------
const tChannelID tChannelID : : InvalidID ;
bool tChannelID : : operator = = ( const tChannelID & arg ) const
{
return source = = arg . source & & nid = = arg . nid & & tid = = arg . tid & & sid = = arg . sid & & rid = = arg . rid ;
}
tChannelID tChannelID : : FromString ( const char * s )
{
char * sourcebuf = NULL ;
int nid ;
int tid ;
int sid ;
int rid = 0 ;
int fields = sscanf ( s , " %a[^-]-%d-%d-%d-%d " , & sourcebuf , & nid , & tid , & sid , & rid ) ;
if ( fields = = 4 | | fields = = 5 ) {
int source = cSource : : FromString ( sourcebuf ) ;
free ( sourcebuf ) ;
if ( source > = 0 )
return tChannelID ( source , nid , tid , sid , rid ) ;
}
return tChannelID : : InvalidID ;
}
const char * tChannelID : : ToString ( void )
{
static char buffer [ 256 ] ;
snprintf ( buffer , sizeof ( buffer ) , rid ? " %s-%d-%d-%d-%d " : " %s-%d-%d-%d " , cSource : : ToString ( source ) , nid , tid , sid , rid ) ;
return buffer ;
}
2002-10-06 10:25:42 +02:00
// -- cChannel ---------------------------------------------------------------
char * cChannel : : buffer = NULL ;
cChannel : : cChannel ( void )
{
2004-01-04 12:30:00 +01:00
memset ( & __BeginData__ , 0 , ( char * ) & __EndData__ - ( char * ) & __BeginData__ ) ;
2002-10-06 10:25:42 +02:00
inversion = INVERSION_AUTO ;
2002-11-01 10:26:45 +01:00
bandwidth = BANDWIDTH_AUTO ;
coderateH = FEC_AUTO ;
coderateL = FEC_AUTO ;
modulation = QAM_AUTO ;
transmission = TRANSMISSION_MODE_AUTO ;
guard = GUARD_INTERVAL_AUTO ;
hierarchy = HIERARCHY_AUTO ;
2004-01-04 12:30:00 +01:00
modification = CHANNELMOD_NONE ;
}
cChannel : : cChannel ( const cChannel * Channel )
{
* this = * Channel ;
* name = 0 ;
vpid = 0 ;
ppid = 0 ;
apid1 = 0 ;
apid2 = 0 ;
dpid1 = 0 ;
dpid2 = 0 ;
tpid = 0 ;
caids [ 0 ] = 0 ;
nid = 0 ;
tid = 0 ;
sid = 0 ;
rid = 0 ;
number = 0 ;
groupSep = false ;
modification = CHANNELMOD_NONE ;
2002-10-06 10:25:42 +02:00
}
2002-11-10 15:50:21 +01:00
cChannel & cChannel : : operator = ( const cChannel & Channel )
2002-10-06 10:25:42 +02:00
{
2002-11-10 15:50:21 +01:00
memcpy ( & __BeginData__ , & Channel . __BeginData__ , ( char * ) & Channel . __EndData__ - ( char * ) & Channel . __BeginData__ ) ;
return * this ;
}
2004-01-04 12:30:00 +01:00
int cChannel : : Transponder ( void ) const
2002-11-10 15:50:21 +01:00
{
2004-01-04 12:30:00 +01:00
int tf = frequency ;
while ( tf > 20000 )
tf / = 1000 ;
return tf ;
2002-11-10 15:50:21 +01:00
}
2002-11-24 14:48:38 +01:00
tChannelID cChannel : : GetChannelID ( void ) const
2002-11-10 15:50:21 +01:00
{
2004-01-05 12:55:07 +01:00
return tChannelID ( source , nid , ( nid | | tid ) ? tid : Transponder ( ) , sid , rid ) ;
2004-01-04 12:30:00 +01:00
}
int cChannel : : Modification ( int Mask )
{
int Result = modification & Mask ;
modification = CHANNELMOD_NONE ;
return Result ;
}
2004-01-11 15:54:37 +01:00
bool cChannel : : SetSatTransponderData ( int Source , int Frequency , char Polarization , int Srate , int CoderateH , bool Log )
{
// Workarounds for broadcaster stupidity:
// Some providers broadcast the transponder frequency of their channels with two different
// values (like 12551 and 12552), so we need to allow for a little tolerance here
if ( abs ( frequency - Frequency ) < = 1 )
Frequency = frequency ;
// Sometimes the transponder frequency is set to 0, which is just wrong
if ( Frequency = = 0 )
return false ;
if ( source ! = Source | | frequency ! = Frequency | | polarization ! = Polarization | | srate ! = Srate | | coderateH ! = CoderateH ) {
if ( Log )
dsyslog ( " changing transponder data of channel %d from %s:%d:%c:%d:%d to %s:%d:%c:%d:%d " , Number ( ) , cSource : : ToString ( source ) , frequency , polarization , srate , coderateH , cSource : : ToString ( Source ) , Frequency , Polarization , Srate , CoderateH ) ;
source = Source ;
frequency = Frequency ;
polarization = Polarization ;
srate = Srate ;
coderateH = CoderateH ;
modulation = QPSK ;
modification | = CHANNELMOD_TRANSP ;
Channels . SetModified ( ) ;
}
return true ;
}
bool cChannel : : SetCableTransponderData ( int Source , int Frequency , int Modulation , int Srate , int CoderateH , bool Log )
{
if ( source ! = Source | | frequency ! = Frequency | | modulation ! = Modulation | | srate ! = Srate | | coderateH ! = CoderateH ) {
if ( Log )
dsyslog ( " changing transponder data of channel %d from %s:%d:%d:%d:%d to %s:%d:%d:%d:%d " , Number ( ) , cSource : : ToString ( source ) , frequency , modulation , srate , coderateH , cSource : : ToString ( Source ) , Frequency , Modulation , Srate , CoderateH ) ;
source = Source ;
frequency = Frequency ;
modulation = Modulation ;
srate = Srate ;
coderateH = CoderateH ;
modification | = CHANNELMOD_TRANSP ;
Channels . SetModified ( ) ;
}
return true ;
}
bool cChannel : : SetTerrTransponderData ( int Source , int Frequency , int Bandwidth , int Modulation , int Hierarchy , int CoderateH , int CoderateL , int Guard , int Transmission , bool Log )
{
if ( source ! = Source | | frequency ! = Frequency | | bandwidth ! = Bandwidth | | modulation ! = Modulation | | hierarchy ! = Hierarchy | | coderateH ! = CoderateH | | coderateL ! = CoderateL | | guard ! = Guard | | transmission ! = Transmission ) {
if ( Log )
dsyslog ( " changing transponder data of channel %d from %s:%d:%d:%d:%d:%d:%d:%d:%d to %s:%d:%d:%d:%d:%d:%d:%d:%d " , Number ( ) , cSource : : ToString ( source ) , frequency , bandwidth , modulation , hierarchy , coderateH , coderateL , guard , transmission , cSource : : ToString ( Source ) , Frequency , Bandwidth , Modulation , Hierarchy , CoderateH , CoderateL , Guard , Transmission ) ;
source = Source ;
frequency = Frequency ;
bandwidth = Bandwidth ;
modulation = Modulation ;
hierarchy = Hierarchy ;
coderateH = CoderateH ;
coderateL = CoderateL ;
guard = Guard ;
transmission = Transmission ;
modification | = CHANNELMOD_TRANSP ;
Channels . SetModified ( ) ;
}
return true ;
}
2004-01-04 12:30:00 +01:00
void cChannel : : SetId ( int Nid , int Tid , int Sid , int Rid , bool Log )
{
if ( nid ! = Nid | | tid ! = Tid | | sid ! = Sid | | rid ! = Rid ) {
if ( Log )
dsyslog ( " changing id of channel %d from %d-%d-%d-%d to %d-%d-%d-%d " , Number ( ) , nid , tid , sid , rid , Nid , Tid , Sid , Rid ) ;
nid = Nid ;
tid = Tid ;
sid = Sid ;
rid = Rid ;
modification | = CHANNELMOD_ID ;
Channels . SetModified ( ) ;
}
}
void cChannel : : SetName ( const char * Name , bool Log )
{
if ( ! isempty ( Name ) & & strcmp ( name , Name ) ! = 0 ) {
if ( Log )
dsyslog ( " changing name of channel %d from '%s' to '%s' " , Number ( ) , name , Name ) ;
strn0cpy ( name , Name , MaxChannelName ) ;
modification | = CHANNELMOD_NAME ;
Channels . SetModified ( ) ;
}
}
void cChannel : : SetPids ( int Vpid , int Ppid , int Apid1 , int Apid2 , int Dpid1 , int Dpid2 , int Tpid )
{
//XXX if (vpid != Vpid || ppid != Ppid || apid1 != Apid1 || apid2 != Apid2 || dpid1 != Dpid1 || dpid2 != Dpid2 || tpid != Tpid) {
if ( vpid ! = Vpid | | ppid ! = Ppid | | apid1 ! = Apid1 | | ( Apid2 & & apid2 ! = Apid2 ) | | dpid1 ! = Dpid1 | | dpid2 ! = Dpid2 | | tpid ! = Tpid ) {
dsyslog ( " changing pids of channel %d from %d+%d:%d,%d;%d,%d:%d to %d+%d:%d,%d;%d,%d:%d " , Number ( ) , vpid , ppid , apid1 , apid2 , dpid1 , dpid2 , tpid , Vpid , Ppid , Apid1 , Apid2 , Dpid1 , Dpid2 , Tpid ) ;
vpid = Vpid ;
ppid = Ppid ;
apid1 = Apid1 ;
if ( Apid2 ) //XXX should we actually react here?
apid2 = Apid2 ;
dpid1 = Dpid1 ;
dpid2 = Dpid2 ;
tpid = Tpid ;
modification | = CHANNELMOD_PIDS ;
Channels . SetModified ( ) ;
}
}
void cChannel : : SetCaIds ( const int * CaIds )
{
if ( caids [ 0 ] & & caids [ 0 ] < = 0x00FF )
return ; // special values will not be overwritten
bool modified = false ;
for ( int i = 0 ; i < MAXCAIDS ; i + + ) {
if ( caids [ i ] ! = CaIds [ i ] ) {
modified = true ;
break ;
}
if ( ! caids [ i ] | | ! CaIds [ i ] )
break ;
}
if ( modified ) {
char OldCaIdsBuf [ MAXCAIDS * 5 + 10 ] ; // 5: 4 digits plus delimiting ',', 10: paranoia
char NewCaIdsBuf [ MAXCAIDS * 5 + 10 ] ;
char * qo = OldCaIdsBuf ;
char * qn = NewCaIdsBuf ;
int i ;
for ( i = 0 ; i < MAXCAIDS ; i + + ) {
if ( i = = 0 | | caids [ i ] )
qo + = snprintf ( qo , sizeof ( OldCaIdsBuf ) , " %s%X " , i > 0 ? " , " : " " , caids [ i ] ) ;
if ( ! caids [ i ] )
break ;
}
for ( i = 0 ; i < MAXCAIDS ; i + + ) {
if ( i = = 0 | | CaIds [ i ] )
qn + = snprintf ( qn , sizeof ( NewCaIdsBuf ) , " %s%X " , i > 0 ? " , " : " " , CaIds [ i ] ) ;
caids [ i ] = CaIds [ i ] ;
if ( ! CaIds [ i ] )
break ;
}
caids [ i ] = 0 ;
* qo = * qn = 0 ;
dsyslog ( " changing caids of channel %d from %s to %s " , Number ( ) , OldCaIdsBuf , NewCaIdsBuf ) ;
modification | = CHANNELMOD_CA ;
Channels . SetModified ( ) ;
}
}
void cChannel : : SetCaDescriptors ( int Level )
{
if ( Level > 0 ) {
modification | = CHANNELMOD_CA ;
Channels . SetModified ( ) ;
if ( Level > 1 )
dsyslog ( " changing ca descriptors of channel %d " , Number ( ) ) ;
}
2002-10-06 10:25:42 +02:00
}
static int PrintParameter ( char * p , char Name , int Value )
{
2002-11-01 10:26:45 +01:00
return Value > = 0 & & Value ! = 999 ? sprintf ( p , " %c%d " , Name , Value ) : 0 ;
2002-10-06 10:25:42 +02:00
}
const char * cChannel : : ParametersToString ( void )
{
char type = * cSource : : ToString ( source ) ;
2002-11-08 14:19:22 +01:00
if ( isdigit ( type ) )
type = ' S ' ;
2002-10-06 10:25:42 +02:00
# define ST(s) if (strchr(s, type))
static char buffer [ 64 ] ;
char * q = buffer ;
* q = 0 ;
ST ( " S " ) q + = sprintf ( q , " %c " , polarization ) ;
ST ( " CST " ) q + = PrintParameter ( q , ' I ' , MapToUser ( inversion , InversionValues ) ) ;
ST ( " CST " ) q + = PrintParameter ( q , ' C ' , MapToUser ( coderateH , CoderateValues ) ) ;
ST ( " T " ) q + = PrintParameter ( q , ' D ' , MapToUser ( coderateL , CoderateValues ) ) ;
ST ( " C T " ) q + = PrintParameter ( q , ' M ' , MapToUser ( modulation , ModulationValues ) ) ;
ST ( " T " ) q + = PrintParameter ( q , ' B ' , MapToUser ( bandwidth , BandwidthValues ) ) ;
ST ( " T " ) q + = PrintParameter ( q , ' T ' , MapToUser ( transmission , TransmissionValues ) ) ;
ST ( " T " ) q + = PrintParameter ( q , ' G ' , MapToUser ( guard , GuardValues ) ) ;
ST ( " T " ) q + = PrintParameter ( q , ' Y ' , MapToUser ( hierarchy , HierarchyValues ) ) ;
return buffer ;
}
static const char * ParseParameter ( const char * s , int & Value , const tChannelParameterMap * Map )
{
if ( * + + s ) {
char * p = NULL ;
errno = 0 ;
int n = strtol ( s , & p , 10 ) ;
if ( ! errno & & p ! = s ) {
2002-11-01 10:26:45 +01:00
Value = MapToDriver ( n , Map ) ;
if ( Value > = 0 )
2002-10-06 10:25:42 +02:00
return p ;
}
}
esyslog ( " ERROR: illegal value for parameter '%c' " , * ( s - 1 ) ) ;
return NULL ;
}
bool cChannel : : StringToParameters ( const char * s )
{
while ( s & & * s ) {
switch ( toupper ( * s ) ) {
case ' B ' : s = ParseParameter ( s , bandwidth , BandwidthValues ) ; break ;
case ' C ' : s = ParseParameter ( s , coderateH , CoderateValues ) ; break ;
case ' D ' : s = ParseParameter ( s , coderateL , CoderateValues ) ; break ;
case ' G ' : s = ParseParameter ( s , guard , GuardValues ) ; break ;
case ' H ' : polarization = * s + + ; break ;
case ' I ' : s = ParseParameter ( s , inversion , InversionValues ) ; break ;
2004-01-11 15:54:37 +01:00
case ' L ' : polarization = * s + + ; break ;
2002-10-06 10:25:42 +02:00
case ' M ' : s = ParseParameter ( s , modulation , ModulationValues ) ; break ;
2004-01-11 15:54:37 +01:00
case ' R ' : polarization = * s + + ; break ;
2002-10-06 10:25:42 +02:00
case ' T ' : s = ParseParameter ( s , transmission , TransmissionValues ) ; break ;
case ' V ' : polarization = * s + + ; break ;
case ' Y ' : s = ParseParameter ( s , hierarchy , HierarchyValues ) ; break ;
default : esyslog ( " ERROR: unknown parameter key '%c' " , * s ) ;
return false ;
}
}
return true ;
}
const char * cChannel : : ToText ( cChannel * Channel )
{
char buf [ MaxChannelName * 2 ] ;
char * s = Channel - > name ;
if ( strchr ( s , ' : ' ) ) {
s = strcpy ( buf , s ) ;
strreplace ( s , ' : ' , ' | ' ) ;
}
free ( buffer ) ;
2002-10-19 15:33:37 +02:00
if ( Channel - > groupSep ) {
if ( Channel - > number )
asprintf ( & buffer , " :@%d %s \n " , Channel - > number , s ) ;
else
asprintf ( & buffer , " :%s \n " , s ) ;
}
2002-10-06 10:25:42 +02:00
else {
2003-04-26 11:58:54 +02:00
char vpidbuf [ 32 ] ;
char * q = vpidbuf ;
q + = snprintf ( q , sizeof ( vpidbuf ) , " %d " , Channel - > vpid ) ;
2004-01-04 12:30:00 +01:00
if ( Channel - > ppid & & Channel - > ppid ! = Channel - > vpid )
2003-04-26 11:58:54 +02:00
q + = snprintf ( q , sizeof ( vpidbuf ) - ( q - vpidbuf ) , " +%d " , Channel - > ppid ) ;
* q = 0 ;
2004-01-04 12:30:00 +01:00
char apidbuf [ MAXAPIDS * 2 * 6 + 10 ] ; // 2: Apids and Dpids, 6: 5 digits plus delimiting ',' or ';', 10: paranoia
2003-04-26 11:58:54 +02:00
q = apidbuf ;
2002-10-06 10:25:42 +02:00
q + = snprintf ( q , sizeof ( apidbuf ) , " %d " , Channel - > apid1 ) ;
if ( Channel - > apid2 )
q + = snprintf ( q , sizeof ( apidbuf ) - ( q - apidbuf ) , " ,%d " , Channel - > apid2 ) ;
if ( Channel - > dpid1 | | Channel - > dpid2 )
q + = snprintf ( q , sizeof ( apidbuf ) - ( q - apidbuf ) , " ;%d " , Channel - > dpid1 ) ;
if ( Channel - > dpid2 )
q + = snprintf ( q , sizeof ( apidbuf ) - ( q - apidbuf ) , " ,%d " , Channel - > dpid2 ) ;
* q = 0 ;
2004-01-04 12:30:00 +01:00
char caidbuf [ MAXCAIDS * 5 + 10 ] ; // 5: 4 digits plus delimiting ',', 10: paranoia
q = caidbuf ;
for ( int i = 0 ; i < MAXCAIDS ; i + + ) {
if ( i = = 0 | | Channel - > caids [ i ] )
q + = snprintf ( q , sizeof ( caidbuf ) , " %s%X " , i > 0 ? " , " : " " , Channel - > caids [ i ] ) ;
if ( ! Channel - > caids [ i ] )
break ;
}
* q = 0 ;
asprintf ( & buffer , " %s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d \n " , s , Channel - > frequency , Channel - > ParametersToString ( ) , cSource : : ToString ( Channel - > source ) , Channel - > srate , vpidbuf , apidbuf , Channel - > tpid , caidbuf , Channel - > sid , Channel - > nid , Channel - > tid , Channel - > rid ) ;
2002-10-06 10:25:42 +02:00
}
return buffer ;
}
const char * cChannel : : ToText ( void )
{
return ToText ( this ) ;
}
2002-11-10 15:50:21 +01:00
bool cChannel : : Parse ( const char * s , bool AllowNonUniqueID )
2002-10-06 10:25:42 +02:00
{
2003-09-09 18:55:26 +02:00
bool ok = true ;
2002-10-06 10:25:42 +02:00
if ( * s = = ' : ' ) {
2002-10-19 15:33:37 +02:00
groupSep = true ;
if ( * + + s = = ' @ ' & & * + + s ) {
char * p = NULL ;
errno = 0 ;
int n = strtol ( s , & p , 10 ) ;
if ( ! errno & & p ! = s & & n > 0 ) {
number = n ;
s = p ;
}
2002-10-06 10:25:42 +02:00
}
2002-10-19 15:33:37 +02:00
strn0cpy ( name , skipspace ( s ) , MaxChannelName ) ;
2002-10-06 10:25:42 +02:00
}
else {
groupSep = false ;
char * namebuf = NULL ;
char * sourcebuf = NULL ;
char * parambuf = NULL ;
2003-04-26 11:58:54 +02:00
char * vpidbuf = NULL ;
2002-10-06 10:25:42 +02:00
char * apidbuf = NULL ;
2004-01-04 12:30:00 +01:00
char * caidbuf = NULL ;
int fields = sscanf ( s , " %a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d " , & namebuf , & frequency , & parambuf , & sourcebuf , & srate , & vpidbuf , & apidbuf , & tpid , & caidbuf , & sid , & nid , & tid , & rid ) ;
2002-10-06 10:25:42 +02:00
if ( fields > = 9 ) {
if ( fields = = 9 ) {
// allow reading of old format
2004-01-04 12:30:00 +01:00
sid = atoi ( caidbuf ) ;
delete caidbuf ;
caidbuf = NULL ;
caids [ 0 ] = tpid ;
caids [ 1 ] = 0 ;
2002-10-06 10:25:42 +02:00
tpid = 0 ;
}
2003-04-26 11:58:54 +02:00
vpid = ppid = 0 ;
2002-10-06 10:25:42 +02:00
apid1 = apid2 = 0 ;
dpid1 = dpid2 = 0 ;
2003-09-09 18:55:26 +02:00
ok = false ;
2003-04-26 11:58:54 +02:00
if ( parambuf & & sourcebuf & & vpidbuf & & apidbuf ) {
2002-10-06 10:25:42 +02:00
ok = StringToParameters ( parambuf ) & & ( source = cSource : : FromString ( sourcebuf ) ) > = 0 ;
2004-01-04 12:30:00 +01:00
2003-04-26 11:58:54 +02:00
char * p = strchr ( vpidbuf , ' + ' ) ;
if ( p )
* p + + = 0 ;
sscanf ( vpidbuf , " %d " , & vpid ) ;
if ( p )
sscanf ( p , " %d " , & ppid ) ;
2004-01-04 12:30:00 +01:00
else
ppid = vpid ;
2003-04-26 11:58:54 +02:00
p = strchr ( apidbuf , ' ; ' ) ;
2002-10-06 10:25:42 +02:00
if ( p )
* p + + = 0 ;
sscanf ( apidbuf , " %d ,%d " , & apid1 , & apid2 ) ;
if ( p )
sscanf ( p , " %d ,%d " , & dpid1 , & dpid2 ) ;
2004-01-04 12:30:00 +01:00
if ( caidbuf ) {
char * p = caidbuf ;
char * q ;
int NumCaIds = 0 ;
while ( ( q = strtok ( p , " , " ) ) ! = NULL ) {
if ( NumCaIds < MAXCAIDS ) {
caids [ NumCaIds + + ] = strtol ( q , NULL , 16 ) & 0xFFFF ;
if ( NumCaIds = = 1 & & caids [ 0 ] < = 0x00FF )
break ;
}
else
esyslog ( " ERROR: too many CA ids! " ) ; // no need to set ok to 'false'
p = NULL ;
}
caids [ NumCaIds ] = 0 ;
}
2002-10-06 10:25:42 +02:00
}
strn0cpy ( name , namebuf , MaxChannelName ) ;
free ( parambuf ) ;
free ( sourcebuf ) ;
2003-04-26 11:58:54 +02:00
free ( vpidbuf ) ;
2002-10-06 10:25:42 +02:00
free ( apidbuf ) ;
2004-01-04 12:30:00 +01:00
free ( caidbuf ) ;
2002-10-06 10:25:42 +02:00
free ( namebuf ) ;
2003-10-17 15:42:40 +02:00
if ( ! GetChannelID ( ) . Valid ( ) ) {
esyslog ( " ERROR: channel data results in invalid ID! " ) ;
return false ;
}
2002-11-10 15:50:21 +01:00
if ( ! AllowNonUniqueID & & Channels . GetByChannelID ( GetChannelID ( ) ) ) {
esyslog ( " ERROR: channel data not unique! " ) ;
return false ;
}
2002-10-06 10:25:42 +02:00
}
else
return false ;
}
strreplace ( name , ' | ' , ' : ' ) ;
2003-09-09 18:55:26 +02:00
return ok ;
2002-10-06 10:25:42 +02:00
}
bool cChannel : : Save ( FILE * f )
{
return fprintf ( f , ToText ( ) ) > 0 ;
}
// -- cChannels --------------------------------------------------------------
cChannels Channels ;
2004-01-04 12:30:00 +01:00
cChannels : : cChannels ( void )
{
maxNumber = 0 ;
modified = false ;
}
2003-08-16 09:18:52 +02:00
bool cChannels : : Load ( const char * FileName , bool AllowComments , bool MustExist )
2002-10-06 10:25:42 +02:00
{
2003-08-16 09:18:52 +02:00
if ( cConfig < cChannel > : : Load ( FileName , AllowComments , MustExist ) ) {
2002-10-06 10:25:42 +02:00
ReNumber ( ) ;
return true ;
}
return false ;
}
int cChannels : : GetNextGroup ( int Idx )
{
cChannel * channel = Get ( + + Idx ) ;
2002-11-29 14:19:08 +01:00
while ( channel & & ! ( channel - > GroupSep ( ) & & * channel - > Name ( ) ) )
2002-10-06 10:25:42 +02:00
channel = Get ( + + Idx ) ;
return channel ? Idx : - 1 ;
}
int cChannels : : GetPrevGroup ( int Idx )
{
cChannel * channel = Get ( - - Idx ) ;
2002-11-29 14:19:08 +01:00
while ( channel & & ! ( channel - > GroupSep ( ) & & * channel - > Name ( ) ) )
2002-10-06 10:25:42 +02:00
channel = Get ( - - Idx ) ;
return channel ? Idx : - 1 ;
}
int cChannels : : GetNextNormal ( int Idx )
{
cChannel * channel = Get ( + + Idx ) ;
while ( channel & & channel - > GroupSep ( ) )
channel = Get ( + + Idx ) ;
return channel ? Idx : - 1 ;
}
void cChannels : : ReNumber ( void )
{
2002-10-19 15:33:37 +02:00
int Number = 1 ;
for ( cChannel * channel = First ( ) ; channel ; channel = Next ( channel ) ) {
if ( channel - > GroupSep ( ) ) {
if ( channel - > Number ( ) > Number )
Number = channel - > Number ( ) ;
}
2003-10-03 15:16:08 +02:00
else {
maxNumber = Number ;
2002-10-19 15:33:37 +02:00
channel - > SetNumber ( Number + + ) ;
2003-10-03 15:16:08 +02:00
}
2002-10-19 15:33:37 +02:00
}
2002-10-06 10:25:42 +02:00
}
2002-10-19 15:33:37 +02:00
cChannel * cChannels : : GetByNumber ( int Number , int SkipGap )
2002-10-06 10:25:42 +02:00
{
2002-10-19 15:33:37 +02:00
cChannel * previous = NULL ;
for ( cChannel * channel = First ( ) ; channel ; channel = Next ( channel ) ) {
if ( ! channel - > GroupSep ( ) ) {
if ( channel - > Number ( ) = = Number )
return channel ;
else if ( SkipGap & & channel - > Number ( ) > Number )
return SkipGap > 0 ? channel : previous ;
previous = channel ;
}
}
2002-10-06 10:25:42 +02:00
return NULL ;
}
2004-01-04 12:30:00 +01:00
cChannel * cChannels : : GetByServiceID ( int Source , int Transponder , unsigned short ServiceID )
2002-11-10 15:50:21 +01:00
{
for ( cChannel * channel = First ( ) ; channel ; channel = Next ( channel ) ) {
2004-01-04 12:30:00 +01:00
if ( ! channel - > GroupSep ( ) & & channel - > Source ( ) = = Source & & ISTRANSPONDER ( channel - > Transponder ( ) , Transponder ) & & channel - > Sid ( ) = = ServiceID )
2002-11-10 15:50:21 +01:00
return channel ;
}
return NULL ;
}
2002-11-24 14:48:38 +01:00
cChannel * cChannels : : GetByChannelID ( tChannelID ChannelID , bool TryWithoutRid )
2002-10-06 10:25:42 +02:00
{
2002-10-19 15:33:37 +02:00
for ( cChannel * channel = First ( ) ; channel ; channel = Next ( channel ) ) {
2002-11-10 15:50:21 +01:00
if ( ! channel - > GroupSep ( ) & & channel - > GetChannelID ( ) = = ChannelID )
2002-10-19 15:33:37 +02:00
return channel ;
}
2002-11-24 14:48:38 +01:00
if ( TryWithoutRid ) {
ChannelID . ClrRid ( ) ;
for ( cChannel * channel = First ( ) ; channel ; channel = Next ( channel ) ) {
if ( ! channel - > GroupSep ( ) & & channel - > GetChannelID ( ) . ClrRid ( ) = = ChannelID )
return channel ;
}
}
2002-10-06 10:25:42 +02:00
return NULL ;
}
2002-11-10 15:50:21 +01:00
bool cChannels : : HasUniqueChannelID ( cChannel * NewChannel , cChannel * OldChannel )
{
2002-11-24 14:48:38 +01:00
tChannelID NewChannelID = NewChannel - > GetChannelID ( ) ;
2002-11-10 15:50:21 +01:00
for ( cChannel * channel = First ( ) ; channel ; channel = Next ( channel ) ) {
if ( ! channel - > GroupSep ( ) & & channel ! = OldChannel & & channel - > GetChannelID ( ) = = NewChannelID )
return false ;
}
return true ;
}
2002-10-06 10:25:42 +02:00
bool cChannels : : SwitchTo ( int Number )
{
cChannel * channel = GetByNumber ( Number ) ;
return channel & & cDevice : : PrimaryDevice ( ) - > SwitchChannel ( channel , true ) ;
}
2004-01-04 12:30:00 +01:00
void cChannels : : SetModified ( void )
{
modified = true ;
}
bool cChannels : : Modified ( void )
{
bool Result = modified ;
modified = false ;
return Result ;
}
2004-01-11 15:54:37 +01:00
cChannel * cChannels : : NewChannel ( const cChannel * Transponder , const char * Name , int Nid , int Tid , int Sid , int Rid )
2004-01-04 12:30:00 +01:00
{
2004-01-11 15:54:37 +01:00
if ( Transponder ) {
dsyslog ( " creating new channel '%s' on %s transponder %d with id %d-%d-%d-%d " , Name , cSource : : ToString ( Transponder - > Source ( ) ) , Transponder - > Transponder ( ) , Nid , Tid , Sid , Rid ) ;
cChannel * NewChannel = new cChannel ( Transponder ) ;
Add ( NewChannel ) ;
ReNumber ( ) ;
NewChannel - > SetId ( Nid , Tid , Sid , Rid , false ) ;
NewChannel - > SetName ( Name , false ) ;
return NewChannel ;
}
2004-01-04 12:30:00 +01:00
return NULL ;
}