2002-05-20 11:18:09 +02:00
/*
* eitscan . c : EIT scanner
*
* 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 : eitscan . c 1.18 2004 / 01 / 11 15 : 50 : 59 kls Exp $
2002-05-20 11:18:09 +02:00
*/
# include "eitscan.h"
2002-08-04 14:57:29 +02:00
# include <stdlib.h>
2002-10-06 10:25:42 +02:00
# include "channels.h"
2002-09-04 17:26:02 +02:00
# include "dvbdevice.h"
2002-05-20 11:18:09 +02:00
2004-01-04 12:30:00 +01:00
// --- cScanData -------------------------------------------------------------
class cScanData : public cListObject {
private :
int source ;
int transponder ;
public :
cScanData ( int Source , int Transponder ) ;
virtual bool operator < ( const cListObject & ListObject ) ;
int Source ( void ) { return source ; }
int Transponder ( void ) { return transponder ; }
2004-01-11 15:54:37 +01:00
cChannel * GetChannel ( cList < cChannel > * Channels ) ;
2004-01-04 12:30:00 +01:00
} ;
cScanData : : cScanData ( int Source , int Transponder )
{
source = Source ;
transponder = Transponder ;
}
bool cScanData : : operator < ( const cListObject & ListObject )
{
cScanData * sd = ( cScanData * ) & ListObject ;
return source < sd - > source | | source = = sd - > source & & transponder < sd - > transponder ;
}
2004-01-11 15:54:37 +01:00
cChannel * cScanData : : GetChannel ( cList < cChannel > * Channels )
2004-01-04 12:30:00 +01:00
{
2004-01-11 15:54:37 +01:00
for ( cChannel * Channel = Channels - > First ( ) ; Channel ; Channel = Channels - > Next ( Channel ) ) {
2004-01-04 12:30:00 +01:00
if ( ! Channel - > GroupSep ( ) & & Channel - > Source ( ) = = source & & ISTRANSPONDER ( Channel - > Transponder ( ) , transponder ) )
return Channel ;
}
return NULL ;
}
// --- cScanList -------------------------------------------------------------
class cScanList : public cList < cScanData > {
public :
2004-01-11 15:54:37 +01:00
cScanList ( cList < cChannel > * Channels ) ;
2004-01-04 12:30:00 +01:00
void AddTransponder ( const cChannel * Channel ) ;
} ;
2004-01-11 15:54:37 +01:00
cScanList : : cScanList ( cList < cChannel > * Channels )
2004-01-04 12:30:00 +01:00
{
2004-01-11 15:54:37 +01:00
for ( cChannel * ch = Channels - > First ( ) ; ch ; ch = Channels - > Next ( ch ) )
2004-01-04 12:30:00 +01:00
AddTransponder ( ch ) ;
Sort ( ) ;
}
void cScanList : : AddTransponder ( const cChannel * Channel )
{
for ( cScanData * sd = First ( ) ; sd ; sd = Next ( sd ) ) {
2004-01-11 15:54:37 +01:00
if ( sd - > Source ( ) = = Channel - > Source ( ) & & ISTRANSPONDER ( sd - > Transponder ( ) , Channel - > Transponder ( ) ) )
2004-01-04 12:30:00 +01:00
return ;
}
Add ( new cScanData ( Channel - > Source ( ) , Channel - > Transponder ( ) ) ) ;
}
2004-01-11 15:54:37 +01:00
// --- cTransponderList ------------------------------------------------------
class cTransponderList : public cList < cChannel > {
public :
void AddTransponder ( cChannel * Channel ) ;
} ;
void cTransponderList : : AddTransponder ( cChannel * Channel )
{
for ( cChannel * ch = First ( ) ; ch ; ch = Next ( ch ) ) {
if ( ch - > Source ( ) = = Channel - > Source ( ) & & ch - > Transponder ( ) = = Channel - > Transponder ( ) ) {
delete Channel ;
return ;
}
}
Add ( Channel ) ;
}
2004-01-04 12:30:00 +01:00
// --- cEITScanner -----------------------------------------------------------
2003-05-24 13:38:28 +02:00
cEITScanner EITScanner ;
2002-05-20 11:18:09 +02:00
cEITScanner : : cEITScanner ( void )
{
lastScan = lastActivity = time ( NULL ) ;
2003-09-06 13:22:24 +02:00
currentDevice = NULL ;
2002-05-20 11:18:09 +02:00
currentChannel = 0 ;
2004-01-11 15:54:37 +01:00
numScan = 0 ;
2004-01-04 12:30:00 +01:00
scanList = NULL ;
2004-01-11 15:54:37 +01:00
transponderList = NULL ;
2002-05-20 11:18:09 +02:00
}
cEITScanner : : ~ cEITScanner ( )
{
2004-01-04 12:30:00 +01:00
delete scanList ;
2004-01-11 15:54:37 +01:00
delete transponderList ;
}
void cEITScanner : : AddTransponder ( cChannel * Channel )
{
if ( ! transponderList )
transponderList = new cTransponderList ;
transponderList - > AddTransponder ( Channel ) ;
2002-05-20 11:18:09 +02:00
}
void cEITScanner : : Activity ( void )
{
if ( currentChannel ) {
Channels . SwitchTo ( currentChannel ) ;
currentChannel = 0 ;
}
lastActivity = time ( NULL ) ;
}
void cEITScanner : : Process ( void )
{
if ( Setup . EPGScanTimeout & & Channels . MaxNumber ( ) > 1 ) {
time_t now = time ( NULL ) ;
if ( now - lastScan > ScanTimeout & & now - lastActivity > ActivityTimeout ) {
2004-01-04 12:30:00 +01:00
if ( Channels . Lock ( false , 10 ) ) {
2004-01-11 15:54:37 +01:00
cList < cChannel > * ChannelList = & Channels ;
if ( numScan % 2 = = 0 & & transponderList ) // switch between the list of new transponders and the actual channels in case there are transponders w/o any channels
ChannelList = transponderList ;
2004-01-04 12:30:00 +01:00
if ( ! scanList )
2004-01-11 15:54:37 +01:00
scanList = new cScanList ( ChannelList ) ;
2004-01-04 12:30:00 +01:00
for ( bool AnyDeviceSwitched = false ; ! AnyDeviceSwitched ; ) {
cScanData * ScanData = NULL ;
for ( int i = 0 ; i < cDevice : : NumDevices ( ) ; i + + ) {
2004-01-05 09:56:54 +01:00
if ( ScanData | | ( ScanData = scanList - > First ( ) ) ! = NULL ) {
cDevice * Device = cDevice : : GetDevice ( i ) ;
if ( Device ) {
if ( Device ! = cDevice : : PrimaryDevice ( ) | | ( cDevice : : NumDevices ( ) = = 1 & & Setup . EPGScanTimeout & & now - lastActivity > Setup . EPGScanTimeout * 3600 ) ) {
if ( ! ( Device - > Receiving ( true ) | | Device - > Replaying ( ) ) ) {
2004-01-11 15:54:37 +01:00
cChannel * Channel = ScanData - > GetChannel ( ChannelList ) ;
2004-01-10 16:52:01 +01:00
if ( Channel ) {
//XXX if (Device->ProvidesTransponder(Channel)) {
if ( ( ! Channel - > Ca ( ) | | Channel - > Ca ( ) = = Device - > DeviceNumber ( ) + 1 | | Channel - > Ca ( ) > = 0x0100 ) & & Device - > ProvidesTransponder ( Channel ) ) { //XXX temporary for the 'sky' plugin
if ( Device = = cDevice : : PrimaryDevice ( ) & & ! currentChannel )
currentChannel = Device - > CurrentChannel ( ) ;
currentDevice = Device ; //XXX see also dvbdevice.c!!!
Device - > SwitchChannel ( Channel , false ) ;
currentDevice = NULL ;
scanList - > Del ( ScanData ) ;
ScanData = NULL ;
AnyDeviceSwitched = true ;
}
2003-05-24 13:38:28 +02:00
}
2003-03-16 13:29:55 +01:00
}
}
}
2004-01-04 12:30:00 +01:00
}
2004-01-05 09:56:54 +01:00
else
break ;
2004-01-04 12:30:00 +01:00
}
if ( ScanData & & ! AnyDeviceSwitched ) {
scanList - > Del ( ScanData ) ;
ScanData = NULL ;
}
if ( ! scanList - > Count ( ) ) {
delete scanList ;
scanList = NULL ;
2004-01-11 15:54:37 +01:00
numScan + + ;
if ( ChannelList = = transponderList ) {
delete transponderList ;
transponderList = NULL ;
}
2004-01-04 12:30:00 +01:00
break ;
2002-05-20 11:18:09 +02:00
}
}
2004-01-04 12:30:00 +01:00
}
2004-01-05 09:56:54 +01:00
lastScan = time ( NULL ) ;
Channels . Unlock ( ) ;
2002-05-20 11:18:09 +02:00
}
}
}