2007-09-15 17:38:38 +02:00
/*
* setup . c : IPTV plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author .
*
2008-01-31 23:28:53 +01:00
* $ Id : setup . c , v 1.52 2008 / 01 / 31 22 : 28 : 53 rahrenbe Exp $
2007-09-15 17:38:38 +02:00
*/
2007-09-18 20:48:10 +02:00
# include <string.h>
# include <vdr/device.h>
# include <vdr/interface.h>
2007-10-06 22:57:53 +02:00
# include <vdr/status.h>
2008-01-19 17:24:40 +01:00
# include <vdr/menu.h>
2007-09-18 20:48:10 +02:00
2007-09-15 17:38:38 +02:00
# include "common.h"
# include "config.h"
2007-10-06 22:57:53 +02:00
# include "device.h"
2007-09-15 17:38:38 +02:00
# include "setup.h"
2007-09-16 15:49:35 +02:00
# ifndef trVDR
# define trVDR(s) tr(s)
# endif
2007-09-18 20:48:10 +02:00
// --- cIptvMenuEditChannel --------------------------------------------------
class cIptvMenuEditChannel : public cOsdMenu
{
private :
enum {
eProtocolUDP ,
eProtocolHTTP ,
eProtocolFILE ,
2007-10-15 23:03:45 +02:00
eProtocolEXT ,
2007-09-18 20:48:10 +02:00
eProtocolCount
} ;
struct tIptvChannel {
2007-10-19 23:36:27 +02:00
int frequency , source , protocol , parameter , vpid , ppid , tpid , sid , nid , tid , rid ;
2007-09-18 20:48:10 +02:00
int apid [ MAXAPIDS + 1 ] , dpid [ MAXDPIDS + 1 ] , spid [ MAXSPIDS + 1 ] , caids [ MAXCAIDS + 1 ] ;
2008-01-31 23:28:53 +01:00
int sidscan , pidscan ;
2007-09-18 20:48:10 +02:00
char name [ 256 ] , location [ 256 ] ;
} data ;
cChannel * channel ;
const char * protocols [ eProtocolCount ] ;
void Setup ( void ) ;
2008-01-31 23:28:53 +01:00
cString GetIptvSettings ( const char * Param , int * Parameter , int * SidScan , int * PidScan , int * Protocol ) ;
2007-09-18 20:48:10 +02:00
void GetChannelData ( cChannel * Channel ) ;
void SetChannelData ( cChannel * Channel ) ;
public :
cIptvMenuEditChannel ( cChannel * Channel , bool New = false ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cIptvMenuEditChannel : : cIptvMenuEditChannel ( cChannel * Channel , bool New )
: cOsdMenu ( trVDR ( " Edit channel " ) , 16 )
{
protocols [ eProtocolUDP ] = tr ( " UDP " ) ;
protocols [ eProtocolHTTP ] = tr ( " HTTP " ) ;
protocols [ eProtocolFILE ] = tr ( " FILE " ) ;
2007-10-15 23:03:45 +02:00
protocols [ eProtocolEXT ] = tr ( " EXT " ) ;
2007-09-18 20:48:10 +02:00
channel = Channel ;
GetChannelData ( channel ) ;
if ( New ) {
channel = NULL ;
data . nid = 0 ;
data . tid = 0 ;
data . rid = 0 ;
}
Setup ( ) ;
}
2008-01-31 23:28:53 +01:00
cString cIptvMenuEditChannel : : GetIptvSettings ( const char * Param , int * Parameter , int * SidScan , int * PidScan , int * Protocol )
2007-09-18 20:48:10 +02:00
{
2007-10-20 22:35:06 +02:00
char * tag = NULL ;
char * proto = NULL ;
2007-09-18 20:48:10 +02:00
char * loc = NULL ;
2008-01-31 23:28:53 +01:00
if ( sscanf ( Param , " %a[^|]|S%dP%d|%a[^|]|%a[^|]|%d " , & tag , SidScan , PidScan , & proto , & loc , Parameter ) = = 6 ) {
2007-10-20 22:35:06 +02:00
cString tagstr ( tag , true ) ;
cString protostr ( proto , true ) ;
cString locstr ( loc , true ) ;
// check if IPTV tag
if ( strncasecmp ( * tagstr , " IPTV " , 4 ) = = 0 ) {
// check if protocol is supported and update the pointer
if ( strncasecmp ( * protostr , " UDP " , 3 ) = = 0 )
* Protocol = eProtocolUDP ;
else if ( strncasecmp ( * protostr , " HTTP " , 4 ) = = 0 )
* Protocol = eProtocolHTTP ;
else if ( strncasecmp ( * protostr , " FILE " , 4 ) = = 0 )
* Protocol = eProtocolFILE ;
else if ( strncasecmp ( * protostr , " EXT " , 3 ) = = 0 )
* Protocol = eProtocolEXT ;
else
return NULL ;
// return location
return locstr ;
}
2007-10-15 23:03:45 +02:00
}
2008-01-31 23:28:53 +01:00
else if ( sscanf ( Param , " %a[^|]|%a[^|]|%a[^|]|%d " , & tag , & proto , & loc , Parameter ) = = 4 ) {
cString tagstr ( tag , true ) ;
cString protostr ( proto , true ) ;
cString locstr ( loc , true ) ;
* SidScan = 0 ;
* PidScan = 0 ;
// check if IPTV tag
if ( strncasecmp ( * tagstr , " IPTV " , 4 ) = = 0 ) {
// check if protocol is supported and update the pointer
if ( strncasecmp ( * protostr , " UDP " , 3 ) = = 0 )
* Protocol = eProtocolUDP ;
else if ( strncasecmp ( * protostr , " HTTP " , 4 ) = = 0 )
* Protocol = eProtocolHTTP ;
else if ( strncasecmp ( * protostr , " FILE " , 4 ) = = 0 )
* Protocol = eProtocolFILE ;
else if ( strncasecmp ( * protostr , " EXT " , 3 ) = = 0 )
* Protocol = eProtocolEXT ;
else
return NULL ;
// return location
return locstr ;
}
}
2007-09-18 20:48:10 +02:00
return NULL ;
}
void cIptvMenuEditChannel : : GetChannelData ( cChannel * Channel )
{
if ( Channel ) {
2008-01-31 23:28:53 +01:00
int parameter , protocol , sidscan , pidscan ;
2007-09-18 20:48:10 +02:00
data . frequency = Channel - > Frequency ( ) ;
data . source = Channel - > Source ( ) ;
data . vpid = Channel - > Vpid ( ) ;
data . ppid = Channel - > Ppid ( ) ;
data . tpid = Channel - > Tpid ( ) ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . apid ) ; + + i )
2007-09-18 20:48:10 +02:00
data . apid [ i ] = Channel - > Apid ( i ) ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . dpid ) ; + + i )
2007-09-18 20:48:10 +02:00
data . dpid [ i ] = Channel - > Dpid ( i ) ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . spid ) ; + + i )
2007-09-18 20:48:10 +02:00
data . spid [ i ] = Channel - > Spid ( i ) ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . caids ) ; + + i )
2007-09-18 20:48:10 +02:00
data . caids [ i ] = Channel - > Ca ( i ) ;
data . sid = Channel - > Sid ( ) ;
data . nid = Channel - > Nid ( ) ;
data . tid = Channel - > Tid ( ) ;
data . rid = Channel - > Rid ( ) ;
strn0cpy ( data . name , Channel - > Name ( ) , sizeof ( data . name ) ) ;
2008-01-31 23:28:53 +01:00
strn0cpy ( data . location , * GetIptvSettings ( Channel - > PluginParam ( ) , & parameter , & sidscan , & pidscan , & protocol ) , sizeof ( data . location ) ) ;
data . sidscan = sidscan ;
data . pidscan = pidscan ;
2007-09-18 20:48:10 +02:00
data . protocol = protocol ;
2007-10-19 23:36:27 +02:00
data . parameter = parameter ;
2007-09-18 20:48:10 +02:00
}
else {
data . frequency = 1 ;
data . source = cSource : : FromData ( cSource : : stPlug ) ;
data . vpid = 0 ;
data . ppid = 0 ;
data . tpid = 0 ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . apid ) ; + + i )
2007-09-18 20:48:10 +02:00
data . apid [ i ] = 0 ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . dpid ) ; + + i )
2007-09-18 20:48:10 +02:00
data . dpid [ i ] = 0 ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . spid ) ; + + i )
2007-09-18 20:48:10 +02:00
data . spid [ i ] = 0 ;
2008-01-05 00:36:37 +01:00
for ( unsigned int i = 0 ; i < ARRAY_SIZE ( data . caids ) ; + + i )
2007-09-18 20:48:10 +02:00
data . caids [ i ] = 0 ;
data . sid = 1 ;
data . nid = 0 ;
data . tid = 0 ;
data . rid = 0 ;
strn0cpy ( data . name , " IPTV " , sizeof ( data . name ) ) ;
strn0cpy ( data . location , " 127.0.0.1 " , sizeof ( data . location ) ) ;
2008-01-31 23:28:53 +01:00
data . sidscan = 0 ;
data . pidscan = 0 ;
2007-09-18 20:48:10 +02:00
data . protocol = eProtocolUDP ;
2007-10-19 23:36:27 +02:00
data . parameter = 1234 ;
2007-09-18 20:48:10 +02:00
}
}
void cIptvMenuEditChannel : : SetChannelData ( cChannel * Channel )
{
if ( Channel ) {
cString param ;
char alangs [ MAXAPIDS ] [ MAXLANGCODE2 ] = { " " } ;
char dlangs [ MAXDPIDS ] [ MAXLANGCODE2 ] = { " " } ;
switch ( data . protocol ) {
2007-10-15 23:03:45 +02:00
case eProtocolEXT :
2008-01-31 23:28:53 +01:00
param = cString : : sprintf ( " IPTV|S%dP%d|EXT|%s|%d " , data . sidscan , data . pidscan , data . location , data . parameter ) ;
2007-10-15 23:03:45 +02:00
break ;
2007-09-18 20:48:10 +02:00
case eProtocolFILE :
2008-01-31 23:28:53 +01:00
param = cString : : sprintf ( " IPTV|S%dP%d|FILE|%s|%d " , data . sidscan , data . pidscan , data . location , data . parameter ) ;
2007-09-18 20:48:10 +02:00
break ;
case eProtocolHTTP :
2008-01-31 23:28:53 +01:00
param = cString : : sprintf ( " IPTV|S%dP%d|HTTP|%s|%d " , data . sidscan , data . pidscan , data . location , data . parameter ) ;
2007-09-18 20:48:10 +02:00
break ;
default :
case eProtocolUDP :
2008-01-31 23:28:53 +01:00
param = cString : : sprintf ( " IPTV|S%dP%d|UDP|%s|%d " , data . sidscan , data . pidscan , data . location , data . parameter ) ;
2007-09-18 20:48:10 +02:00
break ;
}
2007-10-27 01:13:24 +02:00
# if defined(APIVERSNUM) && APIVERSNUM < 10510
Channel - > SetPids ( data . vpid , data . ppid , data . apid , alangs , data . dpid , dlangs , data . tpid ) ;
# else
char slangs [ MAXSPIDS ] [ MAXLANGCODE2 ] = { " " } ;
2007-10-14 20:45:34 +02:00
Channel - > SetPids ( data . vpid , data . ppid , data . apid , alangs , data . dpid , dlangs , data . spid , slangs , data . tpid ) ;
2007-10-27 01:13:24 +02:00
# endif
2007-09-18 20:48:10 +02:00
Channel - > SetCaIds ( data . caids ) ;
Channel - > SetId ( data . nid , data . tid , data . sid , data . rid ) ;
Channel - > SetName ( data . name , " " , " IPTV " ) ;
Channel - > SetPlugTransponderData ( cSource : : stPlug , data . frequency , param ) ;
}
}
void cIptvMenuEditChannel : : Setup ( void )
{
int current = Current ( ) ;
Clear ( ) ;
// IPTV specific settings
2007-10-19 19:07:13 +02:00
Add ( new cMenuEditStraItem ( tr ( " Protocol " ) , & data . protocol ,
eProtocolCount , protocols ) ) ;
2007-09-18 20:48:10 +02:00
switch ( data . protocol ) {
case eProtocolFILE :
2007-11-04 16:23:16 +01:00
# if defined(APIVERSNUM) && APIVERSNUM < 10511
2007-09-29 20:15:31 +02:00
Add ( new cMenuEditStrItem ( trVDR ( " File " ) , data . location , sizeof ( data . location ) , trVDR ( FileNameChars ) ) ) ;
2007-11-04 16:23:16 +01:00
# else
Add ( new cMenuEditStrItem ( trVDR ( " File " ) , data . location , sizeof ( data . location ) ) ) ;
# endif
2007-10-19 23:36:27 +02:00
Add ( new cMenuEditIntItem ( tr ( " Delay (ms) " ) , & data . parameter , 0 , 0xFFFF ) ) ;
2007-09-18 20:48:10 +02:00
break ;
2007-10-15 23:03:45 +02:00
case eProtocolEXT :
2007-11-04 16:23:16 +01:00
# if defined(APIVERSNUM) && APIVERSNUM < 10511
2007-10-19 23:36:27 +02:00
Add ( new cMenuEditStrItem ( tr ( " Script " ) , data . location , sizeof ( data . location ) , trVDR ( FileNameChars ) ) ) ;
2007-11-04 16:23:16 +01:00
# else
Add ( new cMenuEditStrItem ( tr ( " Script " ) , data . location , sizeof ( data . location ) ) ) ;
# endif
2007-10-19 23:36:27 +02:00
Add ( new cMenuEditIntItem ( tr ( " Parameter " ) , & data . parameter , 0 , 0xFFFF ) ) ;
2007-10-17 00:13:44 +02:00
break ;
2007-09-18 20:48:10 +02:00
case eProtocolHTTP :
case eProtocolUDP :
default :
2007-11-04 16:23:16 +01:00
# if defined(APIVERSNUM) && APIVERSNUM < 10511
2007-09-29 20:15:31 +02:00
Add ( new cMenuEditStrItem ( tr ( " Address " ) , data . location , sizeof ( data . location ) , trVDR ( FileNameChars ) ) ) ;
2007-11-04 16:23:16 +01:00
# else
Add ( new cMenuEditStrItem ( tr ( " Address " ) , data . location , sizeof ( data . location ) ) ) ;
# endif
2007-10-19 23:36:27 +02:00
Add ( new cMenuEditIntItem ( tr ( " Port " ) , & data . parameter , 0 , 0xFFFF ) ) ;
2007-09-18 20:48:10 +02:00
break ;
}
2008-01-31 23:28:53 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Scan Sid " ) , & data . sidscan ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " Scan Pid " ) , & data . pidscan ) ) ;
2007-09-18 20:48:10 +02:00
// Normal settings
2007-11-04 16:23:16 +01:00
# if defined(APIVERSNUM) && APIVERSNUM < 10511
2007-09-18 20:48:10 +02:00
Add ( new cMenuEditStrItem ( trVDR ( " Name " ) , data . name , sizeof ( data . name ) , trVDR ( FileNameChars ) ) ) ;
2007-11-04 16:23:16 +01:00
# else
Add ( new cMenuEditStrItem ( trVDR ( " Name " ) , data . name , sizeof ( data . name ) ) ) ;
# endif
2007-09-18 20:48:10 +02:00
Add ( new cMenuEditIntItem ( trVDR ( " Frequency " ) , & data . frequency ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Vpid " ) , & data . vpid , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Ppid " ) , & data . ppid , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Apid1 " ) , & data . apid [ 0 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Apid2 " ) , & data . apid [ 1 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Dpid1 " ) , & data . dpid [ 0 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Dpid2 " ) , & data . dpid [ 1 ] , 0 , 0x1FFF ) ) ;
2007-10-27 14:07:40 +02:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10510
2007-10-14 20:51:21 +02:00
Add ( new cMenuEditIntItem ( trVDR ( " Spid1 " ) , & data . spid [ 0 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Spid2 " ) , & data . spid [ 1 ] , 0 , 0x1FFF ) ) ;
2007-10-27 14:07:40 +02:00
# endif
2007-09-18 20:48:10 +02:00
Add ( new cMenuEditIntItem ( trVDR ( " Tpid " ) , & data . tpid , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " CA " ) , & data . caids [ 0 ] , 0 , 0xFFFF ) ) ;
Add ( new cMenuEditIntItem ( trVDR ( " Sid " ) , & data . sid , 1 , 0xFFFF ) ) ;
2007-10-12 01:34:27 +02:00
Add ( new cMenuEditIntItem ( tr ( " Nid " ) , & data . nid , 0 , 0xFFFF ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Tid " ) , & data . tid , 0 , 0xFFFF ) ) ;
2007-10-01 20:14:57 +02:00
Add ( new cMenuEditIntItem ( tr ( " Rid " ) , & data . rid , 0 , 0x1FFF ) ) ;
2007-09-18 20:48:10 +02:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
}
eOSState cIptvMenuEditChannel : : ProcessKey ( eKeys Key )
{
int oldProtocol = data . protocol ;
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
if ( Key = = kOk ) {
cChannel newchannel ;
SetChannelData ( & newchannel ) ;
2007-09-30 19:34:13 +02:00
bool uniquityFailed = false ;
2007-10-01 17:38:44 +02:00
bool firstIncrement = true ;
2007-09-30 19:34:13 +02:00
// Search for identical channels as these will be ignored by vdr
for ( cChannel * iteratorChannel = Channels . First ( ) ; iteratorChannel ;
2008-01-30 22:57:33 +01:00
iteratorChannel = Channels . Next ( iteratorChannel ) ) {
// This is one of the channels cause the uniquity check to fail
if ( ! iteratorChannel - > GroupSep ( ) & & iteratorChannel ! = channel & &
iteratorChannel - > GetChannelID ( ) = = newchannel . GetChannelID ( ) ) {
// See if it has unique Plugin param. If yes then increment
// the corresponding Rid until it is unique
if ( strcmp ( iteratorChannel - > PluginParam ( ) ,
newchannel . PluginParam ( ) ) ) {
// If the channel RID is already at maximum, then fail the
// channel modification
if ( iteratorChannel - > Rid ( ) > = 0x1FFF ) {
debug ( " Cannot increment RID over maximum value \n " ) ;
uniquityFailed = true ;
break ;
}
debug ( " Incrementing conflicting channel RID \n " ) ;
iteratorChannel - > SetId ( iteratorChannel - > Nid ( ) ,
iteratorChannel - > Tid ( ) ,
iteratorChannel - > Sid ( ) ,
firstIncrement ?
0 : iteratorChannel - > Rid ( ) + 1 ) ;
// Try zero Rid:s at first increment. Prevents them from
// creeping slowly towards their maximum value
firstIncrement = false ;
// Re-set the search and start again
iteratorChannel = Channels . First ( ) ;
continue ;
// Cannot work around by incrementing rid because channels
// are actually copies of each other
}
else {
uniquityFailed = true ;
break ;
}
}
}
2007-09-30 19:34:13 +02:00
if ( ! uniquityFailed ) {
2007-09-18 20:48:10 +02:00
if ( channel ) {
SetChannelData ( channel ) ;
isyslog ( " edited channel %d %s " , channel - > Number ( ) , * channel - > ToText ( ) ) ;
state = osBack ;
}
else {
channel = new cChannel ;
SetChannelData ( channel ) ;
Channels . Add ( channel ) ;
Channels . ReNumber ( ) ;
isyslog ( " added channel %d %s " , channel - > Number ( ) , * channel - > ToText ( ) ) ;
state = osUser1 ;
}
Channels . SetModified ( true ) ;
2007-09-30 19:34:13 +02:00
}
2007-09-18 20:48:10 +02:00
else {
2007-09-30 23:38:31 +02:00
Skins . Message ( mtError , tr ( " Cannot find unique channel settings! " ) ) ;
2007-09-18 20:48:10 +02:00
state = osContinue ;
}
}
}
2007-09-19 19:14:03 +02:00
if ( ( Key ! = kNone ) & & ( data . protocol ! = oldProtocol ) ) {
switch ( data . protocol ) {
2007-10-19 19:49:35 +02:00
case eProtocolEXT :
2007-10-20 00:54:03 +02:00
strn0cpy ( data . location , " iptvstream.sh " , sizeof ( data . location ) ) ;
2007-10-19 23:36:27 +02:00
data . parameter = 0 ;
2007-10-19 19:49:35 +02:00
break ;
2007-09-19 19:14:03 +02:00
case eProtocolFILE :
2007-10-20 00:54:03 +02:00
strn0cpy ( data . location , " /video/stream.ts " , sizeof ( data . location ) ) ;
2007-10-19 23:36:27 +02:00
data . parameter = 0 ;
2007-09-19 19:14:03 +02:00
break ;
case eProtocolHTTP :
strn0cpy ( data . location , " 127.0.0.1/TS/1 " , sizeof ( data . location ) ) ;
2007-10-19 23:36:27 +02:00
data . parameter = 3000 ;
2007-09-19 19:14:03 +02:00
break ;
default :
case eProtocolUDP :
strn0cpy ( data . location , " 127.0.0.1 " , sizeof ( data . location ) ) ;
2007-10-19 23:36:27 +02:00
data . parameter = 1234 ;
2007-09-19 19:14:03 +02:00
break ;
}
2007-09-18 20:48:10 +02:00
Setup ( ) ;
2007-09-19 19:14:03 +02:00
}
2007-09-18 20:48:10 +02:00
return state ;
}
// --- cIptvMenuChannelItem --------------------------------------------------
class cIptvMenuChannelItem : public cOsdItem
{
private :
cChannel * channel ;
public :
cIptvMenuChannelItem ( cChannel * Channel ) ;
virtual void Set ( void ) ;
cChannel * Channel ( void ) { return channel ; }
} ;
cIptvMenuChannelItem : : cIptvMenuChannelItem ( cChannel * Channel )
{
channel = Channel ;
Set ( ) ;
}
void cIptvMenuChannelItem : : Set ( void )
{
char * buffer = NULL ;
asprintf ( & buffer , " %d \t %s " , channel - > Number ( ) , channel - > Name ( ) ) ;
SetText ( buffer , false ) ;
}
// --- cIptvMenuChannels -----------------------------------------------------
class cIptvMenuChannels : public cOsdMenu
{
private :
void Setup ( void ) ;
cChannel * GetChannel ( int Index ) ;
void Propagate ( void ) ;
protected :
eOSState Edit ( void ) ;
eOSState New ( void ) ;
eOSState Delete ( void ) ;
2007-09-29 14:33:48 +02:00
eOSState Switch ( void ) ;
2007-09-18 20:48:10 +02:00
public :
cIptvMenuChannels ( ) ;
~ cIptvMenuChannels ( ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cIptvMenuChannels : : cIptvMenuChannels ( void )
: cOsdMenu ( tr ( " IPTV Channels " ) , numdigits ( Channels . MaxNumber ( ) ) + 1 )
{
Setup ( ) ;
Channels . IncBeingEdited ( ) ;
}
cIptvMenuChannels : : ~ cIptvMenuChannels ( )
{
Channels . DecBeingEdited ( ) ;
}
void cIptvMenuChannels : : Setup ( void )
{
Clear ( ) ;
for ( cChannel * channel = Channels . First ( ) ; channel ; channel = Channels . Next ( channel ) ) {
2007-10-20 22:35:06 +02:00
if ( ! channel - > GroupSep ( ) & & channel - > IsPlug ( ) & & ! strncasecmp ( channel - > PluginParam ( ) , " IPTV " , 4 ) ) {
2007-09-18 20:48:10 +02:00
cIptvMenuChannelItem * item = new cIptvMenuChannelItem ( channel ) ;
Add ( item ) ;
}
}
SetHelp ( trVDR ( " Button$Edit " ) , trVDR ( " Button$New " ) , trVDR ( " Button$Delete " ) , NULL ) ;
Display ( ) ;
}
cChannel * cIptvMenuChannels : : GetChannel ( int Index )
{
cIptvMenuChannelItem * p = ( cIptvMenuChannelItem * ) Get ( Index ) ;
return p ? ( cChannel * ) p - > Channel ( ) : NULL ;
}
void cIptvMenuChannels : : Propagate ( void )
{
Channels . ReNumber ( ) ;
for ( cIptvMenuChannelItem * ci = ( cIptvMenuChannelItem * ) First ( ) ; ci ; ci = ( cIptvMenuChannelItem * ) ci - > Next ( ) )
ci - > Set ( ) ;
Display ( ) ;
Channels . SetModified ( true ) ;
}
2007-09-29 14:33:48 +02:00
eOSState cIptvMenuChannels : : Switch ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
cChannel * ch = GetChannel ( Current ( ) ) ;
if ( ch )
return cDevice : : PrimaryDevice ( ) - > SwitchChannel ( ch , true ) ? osEnd : osContinue ;
return osEnd ;
}
2007-09-18 20:48:10 +02:00
eOSState cIptvMenuChannels : : Edit ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
cChannel * ch = GetChannel ( Current ( ) ) ;
if ( ch )
return AddSubMenu ( new cIptvMenuEditChannel ( ch ) ) ;
return osContinue ;
}
eOSState cIptvMenuChannels : : New ( void )
{
if ( HasSubMenu ( ) )
return osContinue ;
return AddSubMenu ( new cIptvMenuEditChannel ( GetChannel ( Current ( ) ) , true ) ) ;
}
eOSState cIptvMenuChannels : : Delete ( void )
{
if ( ! HasSubMenu ( ) & & Count ( ) > 0 ) {
int CurrentChannelNr = cDevice : : CurrentChannel ( ) ;
cChannel * CurrentChannel = Channels . GetByNumber ( CurrentChannelNr ) ;
int Index = Current ( ) ;
cChannel * channel = GetChannel ( Current ( ) ) ;
int DeletedChannel = channel - > Number ( ) ;
// Check if there is a timer using this channel:
if ( channel - > HasTimer ( ) ) {
Skins . Message ( mtError , trVDR ( " Channel is being used by a timer! " ) ) ;
return osContinue ;
}
if ( Interface - > Confirm ( trVDR ( " Delete channel? " ) ) ) {
if ( CurrentChannel & & channel = = CurrentChannel ) {
int n = Channels . GetNextNormal ( CurrentChannel - > Index ( ) ) ;
if ( n < 0 )
n = Channels . GetPrevNormal ( CurrentChannel - > Index ( ) ) ;
CurrentChannel = Channels . Get ( n ) ;
CurrentChannelNr = 0 ; // triggers channel switch below
}
Channels . Del ( channel ) ;
cOsdMenu : : Del ( Index ) ;
Propagate ( ) ;
isyslog ( " channel %d deleted " , DeletedChannel ) ;
if ( CurrentChannel & & CurrentChannel - > Number ( ) ! = CurrentChannelNr ) {
if ( ! cDevice : : PrimaryDevice ( ) - > Replaying ( ) | | cDevice : : PrimaryDevice ( ) - > Transferring ( ) )
Channels . SwitchTo ( CurrentChannel - > Number ( ) ) ;
else
cDevice : : SetCurrentChannel ( CurrentChannel ) ;
}
}
}
return osContinue ;
}
eOSState cIptvMenuChannels : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
switch ( state ) {
case osUser1 : {
cChannel * channel = Channels . Last ( ) ;
if ( channel ) {
Add ( new cIptvMenuChannelItem ( channel ) , true ) ;
return CloseSubMenu ( ) ;
}
}
break ;
default :
if ( state = = osUnknown ) {
switch ( Key ) {
2007-09-29 14:33:48 +02:00
case kOk : return Switch ( ) ;
2007-09-18 20:48:10 +02:00
case kRed : return Edit ( ) ;
case kGreen : return New ( ) ;
case kYellow : return Delete ( ) ;
default : break ;
}
}
}
return state ;
}
2007-10-06 22:57:53 +02:00
// --- cIptvMenuInfo ---------------------------------------------------------
class cIptvMenuInfo : public cOsdMenu
{
private :
enum {
2007-10-07 17:13:48 +02:00
INFO_TIMEOUT_MS = 2000
2007-10-06 22:57:53 +02:00
} ;
2007-10-07 00:15:02 +02:00
cString text ;
2007-10-06 22:57:53 +02:00
cTimeMs timeout ;
2007-10-09 01:51:58 +02:00
unsigned int page ;
2007-10-07 21:06:33 +02:00
void UpdateInfo ( ) ;
2007-10-06 22:57:53 +02:00
public :
cIptvMenuInfo ( ) ;
virtual ~ cIptvMenuInfo ( ) ;
virtual void Display ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cIptvMenuInfo : : cIptvMenuInfo ( )
2007-10-27 01:13:24 +02:00
: cOsdMenu ( tr ( " IPTV Information " ) ) , text ( " " ) , timeout ( ) , page ( IPTV_DEVICE_INFO_GENERAL )
2007-10-06 22:57:53 +02:00
{
2007-10-27 01:13:24 +02:00
timeout . Set ( INFO_TIMEOUT_MS ) ;
2007-10-07 21:06:33 +02:00
UpdateInfo ( ) ;
2007-10-09 18:37:16 +02:00
SetHelp ( tr ( " General " ) , tr ( " Pids " ) , tr ( " Filters " ) , tr ( " Bits/bytes " ) ) ;
2007-10-06 22:57:53 +02:00
}
cIptvMenuInfo : : ~ cIptvMenuInfo ( )
{
}
2007-10-07 21:06:33 +02:00
void cIptvMenuInfo : : UpdateInfo ( )
2007-10-06 22:57:53 +02:00
{
cIptvDevice * device = cIptvDevice : : GetIptvDevice ( cDevice : : ActualDevice ( ) - > CardIndex ( ) ) ;
if ( device )
2007-10-09 01:51:58 +02:00
text = device - > GetInformation ( page ) ;
2007-10-06 22:57:53 +02:00
else
2007-10-07 00:15:02 +02:00
text = cString ( tr ( " IPTV information not available! " ) ) ;
2007-10-06 22:57:53 +02:00
Display ( ) ;
2007-10-07 17:13:48 +02:00
timeout . Set ( INFO_TIMEOUT_MS ) ;
2007-10-06 22:57:53 +02:00
}
void cIptvMenuInfo : : Display ( void )
{
cOsdMenu : : Display ( ) ;
DisplayMenu ( ) - > SetText ( text , true ) ;
if ( text )
cStatus : : MsgOsdTextItem ( text ) ;
}
eOSState cIptvMenuInfo : : ProcessKey ( eKeys Key )
{
switch ( Key ) {
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
case kLeft | k_Repeat :
case kLeft :
case kRight | k_Repeat :
case kRight :
DisplayMenu ( ) - > Scroll ( NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft , NORMALKEY ( Key ) = = kLeft | | NORMALKEY ( Key ) = = kRight ) ;
cStatus : : MsgOsdTextItem ( NULL , NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft ) ;
return osContinue ;
default : break ;
}
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
2007-10-09 01:51:58 +02:00
case kOk : return osBack ;
case kRed : page = IPTV_DEVICE_INFO_GENERAL ;
UpdateInfo ( ) ;
break ;
case kGreen : page = IPTV_DEVICE_INFO_PIDS ;
UpdateInfo ( ) ;
break ;
case kYellow : page = IPTV_DEVICE_INFO_FILTERS ;
UpdateInfo ( ) ;
break ;
2007-10-09 18:37:16 +02:00
case kBlue : IptvConfig . SetUseBytes ( ! IptvConfig . GetUseBytes ( ) ) ;
2007-10-09 01:51:58 +02:00
UpdateInfo ( ) ;
break ;
default : if ( timeout . TimedOut ( ) )
UpdateInfo ( ) ;
state = osContinue ;
break ;
2007-10-06 22:57:53 +02:00
}
}
return state ;
}
2007-09-18 20:48:10 +02:00
// --- cIptvPluginSetup ------------------------------------------------------
cIptvPluginSetup : : cIptvPluginSetup ( )
2007-09-15 17:38:38 +02:00
{
2007-10-06 02:02:50 +02:00
debug ( " cIptvPluginSetup::cIptvPluginSetup() \n " ) ;
2007-09-16 15:38:20 +02:00
tsBufferSize = IptvConfig . GetTsBufferSize ( ) ;
tsBufferPrefill = IptvConfig . GetTsBufferPrefillRatio ( ) ;
2007-10-20 19:26:46 +02:00
extProtocolBasePort = IptvConfig . GetExtProtocolBasePort ( ) ;
2007-09-30 23:38:31 +02:00
sectionFiltering = IptvConfig . GetSectionFiltering ( ) ;
sidScanning = IptvConfig . GetSidScanning ( ) ;
2008-01-30 22:57:33 +01:00
pidScanning = IptvConfig . GetPidScanning ( ) ;
2007-10-06 02:02:50 +02:00
numDisabledFilters = IptvConfig . GetDisabledFiltersCount ( ) ;
if ( numDisabledFilters > SECTION_FILTER_TABLE_SIZE )
numDisabledFilters = SECTION_FILTER_TABLE_SIZE ;
for ( int i = 0 ; i < SECTION_FILTER_TABLE_SIZE ; + + i ) {
disabledFilterIndexes [ i ] = IptvConfig . GetDisabledFilters ( i ) ;
disabledFilterNames [ i ] = tr ( section_filter_table [ i ] . description ) ;
}
2007-09-15 17:38:38 +02:00
Setup ( ) ;
2007-10-06 22:57:53 +02:00
SetHelp ( trVDR ( " Channels " ) , NULL , NULL , trVDR ( " Button$Info " ) ) ;
2007-09-15 17:38:38 +02:00
}
void cIptvPluginSetup : : Setup ( void )
{
int current = Current ( ) ;
2008-01-20 00:17:20 +01:00
2007-09-15 17:38:38 +02:00
Clear ( ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-19 17:24:40 +01:00
help . Clear ( ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
Add ( new cMenuEditIntItem ( tr ( " TS buffer size [MB] " ) , & tsBufferSize , 1 , 4 ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 15:13:28 +01:00
help . Append ( tr ( " Define a ringbuffer size for transport streams in megabytes. \n \n Smaller sizes help memory consumption, but are more prone to buffer overflows. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
2007-10-07 22:08:44 +02:00
Add ( new cMenuEditIntItem ( tr ( " TS buffer prefill ratio [%] " ) , & tsBufferPrefill , 0 , 40 ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 15:13:28 +01:00
help . Append ( tr ( " Define a prefill ratio of the ringbuffer for transport streams before data is transferred to VDR. \n \n This is useful if streaming media over a slow or unreliable connection. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
2008-01-20 15:13:28 +01:00
Add ( new cMenuEditIntItem ( tr ( " EXT protocol base port " ) , & extProtocolBasePort , 0 , 0xFFF7 ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 14:17:36 +01:00
help . Append ( tr ( " Define a base port used by EXT protocol. \n \n The port range is defined by the number of IPTV devices. This setting sets the port which is listened for connections from external applications when using the EXT protocol. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
2008-01-30 22:57:33 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Scan Pid automatically " ) , & pidScanning ) ) ;
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
help . Append ( tr ( " Define whether program ids shall be scanned automatically. \n \n Automatic Pid scanning helps VDR to detect changed pids of streams. " ) ) ;
# endif
2008-01-20 15:13:28 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Use section filtering " ) , & sectionFiltering ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 15:13:28 +01:00
help . Append ( tr ( " Define whether the section filtering shall be used. \n \n Section filtering means that IPTV plugin tries to parse and provide VDR with secondary data about the currently active stream. VDR can then use this data for providing various functionalities such as automatic pid change detection and EPG etc. \n Enabling this feature does not affect streams that do not contain section data. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
2007-10-06 02:02:50 +02:00
if ( sectionFiltering ) {
2008-01-20 15:13:28 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Scan Sid automatically " ) , & sidScanning ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 14:17:36 +01:00
help . Append ( tr ( " Define whether the service id shall be scanned automatically. \n \n Requires the section filtering. Automatic Sid scanning helps VDR to detect changed pids of streams. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
2008-01-20 15:13:28 +01:00
Add ( new cMenuEditIntItem ( tr ( " Disable filters " ) , & numDisabledFilters , 0 , SECTION_FILTER_TABLE_SIZE ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 14:17:36 +01:00
help . Append ( tr ( " Define number of section filters to be disabled. \n \n Certain section filters might cause some unwanted behaviour to VDR such as time being falsely synchronized. By black-listing the filters here useful section data can be left intact for VDR to process. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2008-01-20 00:17:20 +01:00
2007-10-06 02:02:50 +02:00
for ( int i = 0 ; i < numDisabledFilters ; + + i ) {
// TRANSLATORS: note the singular!
2008-01-20 15:13:28 +01:00
Add ( new cMenuEditStraItem ( tr ( " Disable filter " ) , & disabledFilterIndexes [ i ] , SECTION_FILTER_TABLE_SIZE , disabledFilterNames ) ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-20 00:17:20 +01:00
help . Append ( tr ( " Define an ill-behaving filter to be blacklisted. " ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2007-10-06 02:02:50 +02:00
}
}
2008-01-20 00:17:20 +01:00
2007-09-15 17:38:38 +02:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
}
2007-09-18 20:48:10 +02:00
eOSState cIptvPluginSetup : : EditChannel ( void )
{
2007-10-06 02:02:50 +02:00
debug ( " cIptvPluginSetup::EditChannel() \n " ) ;
2007-09-18 20:48:10 +02:00
if ( HasSubMenu ( ) )
return osContinue ;
return AddSubMenu ( new cIptvMenuChannels ( ) ) ;
}
2007-10-06 22:57:53 +02:00
eOSState cIptvPluginSetup : : ShowInfo ( void )
{
debug ( " cIptvPluginSetup::ShowInfo() \n " ) ;
if ( HasSubMenu ( ) )
return osContinue ;
return AddSubMenu ( new cIptvMenuInfo ( ) ) ;
}
2007-09-15 17:38:38 +02:00
eOSState cIptvPluginSetup : : ProcessKey ( eKeys Key )
{
2007-10-06 02:02:50 +02:00
int oldsectionFiltering = sectionFiltering ;
int oldNumDisabledFilters = numDisabledFilters ;
2007-09-15 17:38:38 +02:00
eOSState state = cMenuSetupPage : : ProcessKey ( Key ) ;
2008-01-20 00:17:20 +01:00
2007-09-18 20:48:10 +02:00
if ( state = = osUnknown ) {
switch ( Key ) {
2007-10-06 22:57:53 +02:00
case kRed : return EditChannel ( ) ;
case kBlue : return ShowInfo ( ) ;
2008-01-20 17:15:14 +01:00
# if defined(APIVERSNUM) && APIVERSNUM >= 10513
2008-01-19 17:24:40 +01:00
case kInfo : if ( Current ( ) < help . Size ( ) )
return AddSubMenu ( new cMenuText ( cString : : sprintf ( " %s - %s '%s' " , tr ( " Help " ) , trVDR ( " Plugin " ) , PLUGIN_NAME_I18N ) , help [ Current ( ) ] ) ) ;
2008-01-20 17:15:14 +01:00
# endif
2007-10-06 22:57:53 +02:00
default : state = osContinue ;
2007-09-18 20:48:10 +02:00
}
}
2008-01-20 00:17:20 +01:00
2007-10-06 02:02:50 +02:00
if ( ( Key ! = kNone ) & & ( ( numDisabledFilters ! = oldNumDisabledFilters ) | | ( sectionFiltering ! = oldsectionFiltering ) ) ) {
2007-10-10 22:54:58 +02:00
while ( ( numDisabledFilters < oldNumDisabledFilters ) & & ( oldNumDisabledFilters > 0 ) )
2007-10-06 02:02:50 +02:00
disabledFilterIndexes [ - - oldNumDisabledFilters ] = - 1 ;
Setup ( ) ;
}
2008-01-20 00:17:20 +01:00
2007-09-15 17:38:38 +02:00
return state ;
}
2007-10-06 02:02:50 +02:00
void cIptvPluginSetup : : StoreFilters ( const char * Name , int * Values )
{
char buffer [ SECTION_FILTER_TABLE_SIZE * 4 ] ;
char * q = buffer ;
for ( int i = 0 ; i < SECTION_FILTER_TABLE_SIZE ; + + i ) {
char s [ 3 ] ;
if ( Values [ i ] < 0 )
break ;
if ( q > buffer )
* q + + = ' ' ;
snprintf ( s , sizeof ( s ) , " %d " , Values [ i ] ) ;
strncpy ( q , s , strlen ( s ) ) ;
q + = strlen ( s ) ;
}
* q = 0 ;
debug ( " cIptvPluginSetup::StoreFilters(): %s=%s \n " , Name , buffer ) ;
SetupStore ( Name , buffer ) ;
}
2007-09-15 17:38:38 +02:00
void cIptvPluginSetup : : Store ( void )
{
2007-09-16 15:38:20 +02:00
// Store values into setup.conf
SetupStore ( " TsBufferSize " , tsBufferSize ) ;
SetupStore ( " TsBufferPrefill " , tsBufferPrefill ) ;
2007-10-20 19:26:46 +02:00
SetupStore ( " ExtProtocolBasePort " , extProtocolBasePort ) ;
2007-09-30 23:38:31 +02:00
SetupStore ( " SectionFiltering " , sectionFiltering ) ;
SetupStore ( " SidScanning " , sidScanning ) ;
2008-01-30 22:57:33 +01:00
SetupStore ( " PidScanning " , pidScanning ) ;
2007-10-06 02:02:50 +02:00
StoreFilters ( " DisabledFilters " , disabledFilterIndexes ) ;
2007-09-16 15:38:20 +02:00
// Update global config
IptvConfig . SetTsBufferSize ( tsBufferSize ) ;
IptvConfig . SetTsBufferPrefillRatio ( tsBufferPrefill ) ;
2007-10-20 19:26:46 +02:00
IptvConfig . SetExtProtocolBasePort ( extProtocolBasePort ) ;
2007-09-30 23:38:31 +02:00
IptvConfig . SetSectionFiltering ( sectionFiltering ) ;
IptvConfig . SetSidScanning ( sidScanning ) ;
2008-01-30 22:57:33 +01:00
IptvConfig . SetPidScanning ( pidScanning ) ;
2007-10-06 02:02:50 +02:00
for ( int i = 0 ; i < SECTION_FILTER_TABLE_SIZE ; + + i )
IptvConfig . SetDisabledFilters ( i , disabledFilterIndexes [ i ] ) ;
2007-09-15 17:38:38 +02:00
}