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-17 15:38:11 +01:00
* $ Id : eitscan . c 1.20 2004 / 01 / 17 15 : 38 : 11 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"
2004-01-17 15:38:11 +01:00
# include "interface.h"
2002-05-20 11:18:09 +02:00
2004-01-04 12:30:00 +01:00
// --- cScanData -------------------------------------------------------------
class cScanData : public cListObject {
private :
2004-01-17 13:13:47 +01:00
cChannel channel ;
2004-01-04 12:30:00 +01:00
public :
2004-01-17 13:13:47 +01:00
cScanData ( const cChannel * Channel ) ;
2004-01-04 12:30:00 +01:00
virtual bool operator < ( const cListObject & ListObject ) ;
2004-01-17 13:13:47 +01:00
int Source ( void ) { return channel . Source ( ) ; }
int Transponder ( void ) { return channel . Transponder ( ) ; }
const cChannel * GetChannel ( void ) { return & channel ; }
2004-01-04 12:30:00 +01:00
} ;
2004-01-17 13:13:47 +01:00
cScanData : : cScanData ( const cChannel * Channel )
2004-01-04 12:30:00 +01:00
{
2004-01-17 13:13:47 +01:00
channel = * Channel ;
2004-01-04 12:30:00 +01:00
}
bool cScanData : : operator < ( const cListObject & ListObject )
{
cScanData * sd = ( cScanData * ) & ListObject ;
2004-01-17 13:13:47 +01:00
return Source ( ) < sd - > Source ( ) | | Source ( ) = = sd - > Source ( ) & & Transponder ( ) < sd - > Transponder ( ) ;
2004-01-04 12:30:00 +01:00
}
// --- cScanList -------------------------------------------------------------
class cScanList : public cList < cScanData > {
public :
2004-01-17 13:13:47 +01:00
void AddTransponders ( cList < cChannel > * Channels ) ;
2004-01-04 12:30:00 +01:00
void AddTransponder ( const cChannel * Channel ) ;
} ;
2004-01-17 13:13:47 +01:00
void cScanList : : AddTransponders ( 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 )
{
2004-01-17 13:13:47 +01:00
if ( Channel - > Source ( ) & & Channel - > Transponder ( ) ) {
for ( cScanData * sd = First ( ) ; sd ; sd = Next ( sd ) ) {
if ( sd - > Source ( ) = = Channel - > Source ( ) & & ISTRANSPONDER ( sd - > Transponder ( ) , Channel - > Transponder ( ) ) )
return ;
}
Add ( new cScanData ( Channel ) ) ;
}
2004-01-04 12:30:00 +01:00
}
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-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
}
2004-01-17 15:38:11 +01:00
void cEITScanner : : ForceScan ( void )
{
lastActivity = 0 ;
}
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-17 13:13:47 +01:00
if ( ! scanList ) {
scanList = new cScanList ;
scanList - > AddTransponders ( & Channels ) ;
if ( transponderList ) {
scanList - > AddTransponders ( transponderList ) ;
delete transponderList ;
transponderList = NULL ;
}
}
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-17 13:13:47 +01:00
const cChannel * Channel = ScanData - > GetChannel ( ) ;
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
2004-01-17 15:38:11 +01:00
if ( Device = = cDevice : : PrimaryDevice ( ) & & ! currentChannel ) {
2004-01-10 16:52:01 +01:00
currentChannel = Device - > CurrentChannel ( ) ;
2004-01-17 15:38:11 +01:00
Interface - > Info ( " Starting EPG scan " ) ;
}
2004-01-10 16:52:01 +01:00
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-17 15:38:11 +01:00
if ( lastActivity = = 0 ) // this was a triggered scan
Activity ( ) ;
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
}
}
}