summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2002-03-03 16:12:29 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2002-03-03 16:12:29 +0100
commit9d4456a0a3dc65ee03baaa2fda8f8e0348664997 (patch)
tree365528c26bbc6d4f10b84c455329faa221de5457
parent9f5397b51006f7918c07217b98e91ced547eb6f6 (diff)
downloadvdr-9d4456a0a3dc65ee03baaa2fda8f8e0348664997.tar.gz
vdr-9d4456a0a3dc65ee03baaa2fda8f8e0348664997.tar.bz2
CICAM setup for conditional access channels
-rw-r--r--FORMATS19
-rw-r--r--HISTORY14
-rw-r--r--MANUAL8
-rw-r--r--ca.conf22
-rw-r--r--channels.conf138
-rw-r--r--config.c73
-rw-r--r--config.h23
-rw-r--r--dvbapi.c124
-rw-r--r--dvbapi.h31
-rw-r--r--i18n.c12
-rw-r--r--menu.c65
-rw-r--r--vdr.c3
12 files changed, 415 insertions, 117 deletions
diff --git a/FORMATS b/FORMATS
index 0da29397..91903384 100644
--- a/FORMATS
+++ b/FORMATS
@@ -29,8 +29,9 @@ Video Disk Recorder File Formats
If this channel also carries Dolby Digital sound, the Dolby PIDs follow
the audio PIDs, separated by a semicolon, as in "...:101,102;103,104:..."
- Teletext PID
- - Conditional Access (0 = Free To Air, 1 = can be decrypted by the first
- DVB card, 2 = can be decrypted by the second DVB card)
+ - Conditional Access (0 = Free To Air, 1..4 = explicitly requires the DVB card
+ with the given number, >=100 = requires a specific decryption method defined
+ in 'ca.conf').
- Program Number
Fields marked with ** are only meaningful for DVB-S receivers.
@@ -38,6 +39,20 @@ Video Disk Recorder File Formats
Fields marked with *** are only meaningful for DVB-S and DVB-C receivers.
DVB-T receivers simply ignore these.
+* ca.conf
+
+ This file contains the definitions of the various conditional access code
+ numbers. Anything after (and including) a '#' character is comment.
+ Value lines consist of an integer number, followed by a text describing
+ this decryption method (typically the name of the pay tv service using this
+ decryption method).
+ The special value 0 means "Free To Air", i.e. can be used for channels that
+ don't require additional decryption hardware.
+ The values 1..4 can be used for channels that for some reason explicitly
+ need a given DVB card (for backward compatibility).
+ The values defined in this file are the ones used in the 'Ca' parameter of
+ 'channels.conf'.
+
* timers.conf
This file contains the timer setup.
diff --git a/HISTORY b/HISTORY
index 836de4c5..fd7f35c8 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1048,8 +1048,20 @@ Video Disk Recorder Revision History
- Fixed a crash in case there is no 'epg.data' at program start (thanks to
Andreas Schultz).
-2002-03-01: Version 1.0.0pre3
+2002-03-03: Version 1.0.0pre3
- Fixed parsing 'E' records in epg2html.pl.
- Fixed a deadlock when switching channels via Schedule/Now|Next/Switch (reported
by Martin Hammerschmid).
+- Changed the meaning of the 'Ca' parameter in 'channels.conf'. Each channel can
+ now define which decryption method it needs in order to be accessed. The new
+ configuration file 'ca.conf' contains the defined values, and the default
+ 'channels.conf' has been modifed to contain the new values for 'Premiere World'
+ and 'ORF'. If you use the default 'channels.conf' and have the conditional
+ access hardware to receive encrypted channels, please make sure you copy the
+ file 'ca.conf' into your /video directory (or wherever your configuration files
+ are located) and go into the "Setup" menu and set the CICAM values according
+ to your hardware setup. Currently there are two possible CICAM entries per
+ DVB card, so any card can implement up to two different conditional access
+ modes (besides the default "Free To Air" mode, which is always assumed to be
+ available on any DVB card).
diff --git a/MANUAL b/MANUAL
index 320d24da..c4cda08a 100644
--- a/MANUAL
+++ b/MANUAL
@@ -526,6 +526,14 @@ Video Disk Recorder User's Manual
0 = off
1 = on
+ CaCaps (no default) Defines the "Conditional Access Capabilities" of a DVB
+ card. The value consists of the card number, followed by
+ a list of decryption method values (defined in 'ca.conf').
+ For instance
+ CaCaps = 3 101 102
+ would define that card number 3 is able to decrypt
+ "Premiere World" and the "ORF".
+
* Executing system commands
The "Main" menu option "Commands" allows you to execute any system commands
diff --git a/ca.conf b/ca.conf
new file mode 100644
index 00000000..7024ee42
--- /dev/null
+++ b/ca.conf
@@ -0,0 +1,22 @@
+# Conditional Access configuration for VDR
+#
+# Format:
+#
+# number description
+#
+# Please contact kls@cadsoft.de before assigning a new number
+# to a description, in order to keep them unique.
+
+0 Free To Air
+
+# BetaCrypt
+
+101 Premiere World
+102 ORF
+
+# Special values to "hard code" a channel to a specific DVB card:
+
+1 DVB 1
+2 DVB 2
+3 DVB 3
+4 DVB 4
diff --git a/channels.conf b/channels.conf
index 4642edc5..db1cbf41 100644
--- a/channels.conf
+++ b/channels.conf
@@ -15,8 +15,8 @@ ZDF:11954:h:0:27500:110:120:130:0:28006
3sat:11954:h:0:27500:210:220:230:0:28007
KiKa:11954:h:0:27500:310:320:330:0:28008
arte:11836:h:0:27500:401:402:404:0:28109
-ORF1:12692:h:0:22000:160:161:165:3:13001
-ORF2:12692:h:0:22000:500:501:505:3:13002
+ORF1:12692:h:0:22000:160:161:165:102:13001
+ORF2:12692:h:0:22000:500:501:505:102:13002
ORF Sat:11954:h:0:27500:506:507:0:0:28010
ZDF.info:11954:h:0:27500:610:620:0:0:28011
CNN:12168:v:0:27500:165:100:0:0:28512
@@ -49,82 +49,82 @@ B1:12110:h:0:27500:601:602:604:0:28206
ARD Online-Kanal:12722:h:0:22000:0:701:0:0:0
:Premiere World
Premiere World:11797:h:0:27500:255:256:32:0:8
-Premiere 1:11797:h:0:27500:511:512:0:3:10
-Premiere 2:11797:h:0:27500:1791:1792:0:3:11
-Premiere 3:11797:h:0:27500:2303:2304:0:3:43
-Premiere One:12032:h:0:27500:3071:3072:0:3:51
-Premiere Star:11797:h:0:27500:767:768:0:3:9
-Premiere Sci-Fi:11797:h:0:27500:1535:1536:0:3:41
-Premiere Action:11797:h:0:27500:1023:1024:0:3:20
-Premiere X-Action:11798:h:0:27500:2047:2048:0:3:50
-Premiere Comedy:11797:h:0:27500:1279:1280:0:3:29
-13th Street:12031:h:0:27500:2303:2304:0:3:42
-Studio Universal:12090:V:0:27500:255:256:0:3:36
-Filmpalast:12031:h:0:27500:2559:2560:0:3:516
-Heimatkanal:12031:h:0:27500:2815:2816:0:3:517
-Discovery Channel:12031:h:0:27500:1791:1792:0:3:14
-Planet:12090:V:0:27500:1279:1280:0:3:13
-Fox Kids:12031:h:0:27500:1279:1280:0:3:28
-Fox Kids Türkce:11914:H:0:27500:767:768:8191:3:54
-Junior:12031:h:0:27500:255:256:0:3:19
-K-Toon:12031:h:0:27500:511:512:0:3:12
-Disney Channel:12090:V:0:27500:767:768:0:3:34
-Sunset:12031:h:0:27500:1023:1024:0:3:16
-Krimi&Co:12031:h:0:27500:1535:1536:0:3:23
-Goldstar TV:12031:h:0:27500:3839:3840:0:3:518
-Classica:12031:h:0:27500:767:768:0:3:15
-Seasons:12090:V:0:27500:511:512:0:3:33
+Premiere 1:11797:h:0:27500:511:512:0:101:10
+Premiere 2:11797:h:0:27500:1791:1792:0:101:11
+Premiere 3:11797:h:0:27500:2303:2304:0:101:43
+Premiere One:12032:h:0:27500:3071:3072:0:101:51
+Premiere Star:11797:h:0:27500:767:768:0:101:9
+Premiere Sci-Fi:11797:h:0:27500:1535:1536:0:101:41
+Premiere Action:11797:h:0:27500:1023:1024:0:101:20
+Premiere X-Action:11798:h:0:27500:2047:2048:0:101:50
+Premiere Comedy:11797:h:0:27500:1279:1280:0:101:29
+13th Street:12031:h:0:27500:2303:2304:0:101:42
+Studio Universal:12090:V:0:27500:255:256:0:101:36
+Filmpalast:12031:h:0:27500:2559:2560:0:101:516
+Heimatkanal:12031:h:0:27500:2815:2816:0:101:517
+Discovery Channel:12031:h:0:27500:1791:1792:0:101:14
+Planet:12090:V:0:27500:1279:1280:0:101:13
+Fox Kids:12031:h:0:27500:1279:1280:0:101:28
+Fox Kids Türkce:11914:H:0:27500:767:768:8191:101:54
+Junior:12031:h:0:27500:255:256:0:101:19
+K-Toon:12031:h:0:27500:511:512:0:101:12
+Disney Channel:12090:V:0:27500:767:768:0:101:34
+Sunset:12031:h:0:27500:1023:1024:0:101:16
+Krimi&Co:12031:h:0:27500:1535:1536:0:101:23
+Goldstar TV:12031:h:0:27500:3839:3840:0:101:518
+Classica:12031:h:0:27500:767:768:0:101:15
+Seasons:12090:V:0:27500:511:512:0:101:33
:Cinedom
-Cinedom Deluxe:11758:h:0:27500:255:256,257;259:0:3:189
-Cinedom 1A:11758:h:0:27500:511:512,513:0:3:190
-Cinedom 1B:12070:h:0:27500:1535:1536,1537:0:3:178
-Cinedom 1C:11720:h:0:27500:511:512,513:0:3:180
-Cinedom 1D:11720:h:0:27500:1535:1536,1537:0:3:176
-Cinedom 2A:11758:h:0:27500:1023:1024,1025:0:3:193
-Cinedom 2B:11720:h:0:27500:1279:1280:0:3:183
-Cinedom 2C:12070:h:0:27500:1791:1792:0:3:179
-Cinedom 2D:12070:h:0:27500:511:512:0:3:184
-Cinedom 2E:12070:h:0:27500:1279:1280:0:3:188
-Cinedom 3A:11758:h:0:27500:2559:2560:0:3:192
-Cinedom 3B:11758:h:0:27500:1535:1536:0:3:195
-Cinedom 3C:12070:h:0:27500:767:768:0:3:185
-Cinedom 3D:11720:h:0:27500:1023:1024:0:3:182
-Cinedom 4A:11758:h:0:27500:767:768:0:3:191
-Cinedom 4B:11720:h:0:27500:767:768:0:3:181
-Cinedom 4C:12070:h:0:27500:2047:2048:0:3:187
-Cinedom 5A:11758:h:0:27500:1279:1280:0:3:194
-Cinedom 5B:11720:h:0:27500:1791:1792:0:3:177
-Cinedom 5C:12070:h:0:27500:1023:1024:0:3:186
+Cinedom Deluxe:11758:h:0:27500:255:256,257;259:0:101:189
+Cinedom 1A:11758:h:0:27500:511:512,513:0:101:190
+Cinedom 1B:12070:h:0:27500:1535:1536,1537:0:101:178
+Cinedom 1C:11720:h:0:27500:511:512,513:0:101:180
+Cinedom 1D:11720:h:0:27500:1535:1536,1537:0:101:176
+Cinedom 2A:11758:h:0:27500:1023:1024,1025:0:101:193
+Cinedom 2B:11720:h:0:27500:1279:1280:0:101:183
+Cinedom 2C:12070:h:0:27500:1791:1792:0:101:179
+Cinedom 2D:12070:h:0:27500:511:512:0:101:184
+Cinedom 2E:12070:h:0:27500:1279:1280:0:101:188
+Cinedom 3A:11758:h:0:27500:2559:2560:0:101:192
+Cinedom 3B:11758:h:0:27500:1535:1536:0:101:195
+Cinedom 3C:12070:h:0:27500:767:768:0:101:185
+Cinedom 3D:11720:h:0:27500:1023:1024:0:101:182
+Cinedom 4A:11758:h:0:27500:767:768:0:101:191
+Cinedom 4B:11720:h:0:27500:767:768:0:101:181
+Cinedom 4C:12070:h:0:27500:2047:2048:0:101:187
+Cinedom 5A:11758:h:0:27500:1279:1280:0:101:194
+Cinedom 5B:11720:h:0:27500:1791:1792:0:101:177
+Cinedom 5C:12070:h:0:27500:1023:1024:0:101:186
:Beta Digital
N24:12480:v:0:27500:2047:2048:0:0:47
CNBC:11954:h:0:27500:510:520:0:0:28010
Liberty TV.com:12610:V:0:22000:941:943,942:0:0:12199
:PW Erotic
-Beate-Uhse.TV:11758:h:0:27500:3839:3840:0:3:21
-Blue Movie 1:11758:h:0:27500:1791:1792:0:3:513
-Blue Movie 2:11758:h:0:27500:2047:2048:0:3:514
-Blue Movie 3:11758:h:0:27500:2303:2304:0:3:515
+Beate-Uhse.TV:11758:h:0:27500:3839:3840:0:101:21
+Blue Movie 1:11758:h:0:27500:1791:1792:0:101:513
+Blue Movie 2:11758:h:0:27500:2047:2048:0:101:514
+Blue Movie 3:11758:h:0:27500:2303:2304:0:101:515
:Sportsworld
-Premiere Sport 1:11720:h:0:27500:255:256,257:0:3:17
-Premiere Sport 2:12070:h:0:27500:3839:3840:0:3:27
-Premiere Sport 3:12070:h:0:27500:255:256:0:3:26
+Premiere Sport 1:11720:h:0:27500:255:256,257:0:101:17
+Premiere Sport 2:12070:h:0:27500:3839:3840:0:101:27
+Premiere Sport 3:12070:h:0:27500:255:256:0:101:26
:Formel 1
-Infokanal:11720:h:0:27500:3071:3072:0:3:244
-Multikanal:11720:h:0:27500:2815:2816:0:3:243
-Supersignal:11720:h:0:27500:255:256:0:3:17
-Verfolgerfeld:11720:h:0:27500:2303:2304:0:3:241
-Cockpitkanal:11720:h:0:27500:2559:2560:0:3:242
-Boxengasse:11720:h:0:27500:2047:2048:0:3:240
+Infokanal:11720:h:0:27500:3071:3072:0:101:244
+Multikanal:11720:h:0:27500:2815:2816:0:101:243
+Supersignal:11720:h:0:27500:255:256:0:101:17
+Verfolgerfeld:11720:h:0:27500:2303:2304:0:101:241
+Cockpitkanal:11720:h:0:27500:2559:2560:0:101:242
+Boxengasse:11720:h:0:27500:2047:2048:0:101:240
:Premiere World Bundesliga
-Superdom:11758:h:0:27500:2815:8192:0:3:18
-BuLi-Konferenz:11758:h:0:27500:3327:3328,3329:0:3:215
-BuLi-Spiel 1:11720:h:0:27500:255:256,257:0:3:17
-BuLi-Spiel 2:11720:h:0:27500:2047:2048,2049:0:3:240
-BuLi-Spiel 3:11720:h:0:27500:2303:2304,2305:0:3:241
-BuLi-Spiel 4:11720:h:0:27500:2559:2560,2561:0:3:242
-BuLi-Spiel 5:11720:h:0:27500:2815:2816,2817:0:3:243
-BuLi-Spiel 6:11720:h:0:27500:3071:3072,3073:0:3:244
-BuLi-Spiel 7:11758:h:0:27500:3071:3072,3073:0:3:214
+Superdom:11758:h:0:27500:2815:8192:0:101:18
+BuLi-Konferenz:11758:h:0:27500:3327:3328,3329:0:101:215
+BuLi-Spiel 1:11720:h:0:27500:255:256,257:0:101:17
+BuLi-Spiel 2:11720:h:0:27500:2047:2048,2049:0:101:240
+BuLi-Spiel 3:11720:h:0:27500:2303:2304,2305:0:101:241
+BuLi-Spiel 4:11720:h:0:27500:2559:2560,2561:0:101:242
+BuLi-Spiel 5:11720:h:0:27500:2815:2816,2817:0:101:243
+BuLi-Spiel 6:11720:h:0:27500:3071:3072,3073:0:101:244
+BuLi-Spiel 7:11758:h:0:27500:3071:3072,3073:0:101:214
:
TV Niepokalanow:11876:h:0:27500:305:321:0:0:20601
Mosaico:11934:v:0:27500:165:100:0:0:29010
diff --git a/config.c b/config.c
index 213fe2cf..a91cb8ac 100644
--- a/config.c
+++ b/config.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.c 1.87 2002/02/24 11:59:14 kls Exp $
+ * $Id: config.c 1.88 2002/03/03 16:04:21 kls Exp $
*/
#include "config.h"
@@ -732,6 +732,24 @@ bool cSVDRPhost::Accepts(in_addr_t Address)
return (Address & mask) == addr.s_addr;
}
+// -- cCaDefinition ----------------------------------------------------------
+
+cCaDefinition::cCaDefinition(void)
+{
+ number = 0;
+ description = NULL;
+}
+
+cCaDefinition::~cCaDefinition()
+{
+ delete description;
+}
+
+bool cCaDefinition::Parse(const char *s)
+{
+ return 2 == sscanf(s, "%d %a[^\n]", &number, &description) && description && *description;
+}
+
// -- cKeys ------------------------------------------------------------------
cKeys Keys;
@@ -879,6 +897,21 @@ bool cSVDRPhosts::Acceptable(in_addr_t Address)
return false;
}
+// -- cCaDefinitions ---------------------------------------------------------
+
+cCaDefinitions CaDefinitions;
+
+const cCaDefinition *cCaDefinitions::Get(int Number)
+{
+ cCaDefinition *p = First();
+ while (p) {
+ if (p->Number() == Number)
+ return p;
+ p = (cCaDefinition *)p->Next();
+ }
+ return NULL;
+}
+
// -- cSetup -----------------------------------------------------------------
cSetup Setup;
@@ -921,10 +954,46 @@ cSetup::cSetup(void)
MinUserInactivity = 120;
MultiSpeedMode = 0;
ShowReplayMode = 0;
+ memset(CaCaps, sizeof(CaCaps), 0);
CurrentChannel = -1;
CurrentVolume = MAXVOLUME;
}
+void cSetup::PrintCaCaps(FILE *f, const char *Name)
+{
+ for (int d = 0; d < MAXDVBAPI; d++) {
+ if (CaCaps[d][0]) {
+ fprintf(f, "CaCaps = %d", d + 1);
+ for (int i = 0; i < MAXCACAPS && CaCaps[d][i]; i++)
+ fprintf(f, " %d", CaCaps[d][i]);
+ fprintf(f, "\n");
+ }
+ }
+}
+
+bool cSetup::ParseCaCaps(const char *Value)
+{
+ char *p;
+ int d = strtol(Value, &p, 10);
+ if (d > 0 && d < MAXDVBAPI) {
+ d--;
+ int i = 0;
+ while (p != Value && p && *p) {
+ if (i < MAXCACAPS) {
+ int c = strtol(p, &p, 10);
+ if (c > 0)
+ CaCaps[d][i++] = c;
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
bool cSetup::Parse(char *s)
{
char *p = strchr(s, '=');
@@ -967,6 +1036,7 @@ bool cSetup::Parse(char *s)
else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value);
else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value);
else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value);
+ else if (!strcasecmp(Name, "CaCaps")) return ParseCaCaps(Value);
else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value);
else if (!strcasecmp(Name, "CurrentVolume")) CurrentVolume = atoi(Value);
else
@@ -1047,6 +1117,7 @@ bool cSetup::Save(const char *FileName)
fprintf(f, "MinUserInactivity = %d\n", MinUserInactivity);
fprintf(f, "MultiSpeedMode = %d\n", MultiSpeedMode);
fprintf(f, "ShowReplayMode = %d\n", ShowReplayMode);
+ PrintCaCaps(f, "CaCaps");
fprintf(f, "CurrentChannel = %d\n", CurrentChannel);
fprintf(f, "CurrentVolume = %d\n", CurrentVolume);
if (f.Close()) {
diff --git a/config.h b/config.h
index 52a203ff..f5e83435 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.101 2002/02/26 17:25:30 kls Exp $
+ * $Id: config.h 1.102 2002/03/03 16:04:43 kls Exp $
*/
#ifndef __CONFIG_H
@@ -195,6 +195,18 @@ public:
bool Accepts(in_addr_t Address);
};
+class cCaDefinition : public cListObject {
+private:
+ int number;
+ char *description;
+public:
+ cCaDefinition(void);
+ ~cCaDefinition();
+ bool Parse(const char *s);
+ int Number(void) const { return number; }
+ const char *Description(void) const { return description; }
+ };
+
template<class T> class cConfig : public cList<T> {
private:
char *fileName;
@@ -297,15 +309,23 @@ public:
bool Acceptable(in_addr_t Address);
};
+class cCaDefinitions : public cConfig<cCaDefinition> {
+public:
+ const cCaDefinition *Get(int Number);
+ };
+
extern cChannels Channels;
extern cTimers Timers;
extern cKeys Keys;
extern cCommands Commands;
extern cSVDRPhosts SVDRPhosts;
+extern cCaDefinitions CaDefinitions;
class cSetup {
private:
static char *fileName;
+ void PrintCaCaps(FILE *f, const char *Name);
+ bool ParseCaCaps(const char *Value);
bool Parse(char *s);
public:
// Also adjust cMenuSetup (menu.c) when adding parameters here!
@@ -339,6 +359,7 @@ public:
int MinEventTimeout, MinUserInactivity;
int MultiSpeedMode;
int ShowReplayMode;
+ int CaCaps[MAXDVBAPI][MAXCACAPS];
int CurrentChannel;
int CurrentVolume;
cSetup(void);
diff --git a/dvbapi.c b/dvbapi.c
index c55142e1..2f1ca145 100644
--- a/dvbapi.c
+++ b/dvbapi.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbapi.c 1.153 2002/03/02 09:37:56 kls Exp $
+ * $Id: dvbapi.c 1.154 2002/03/03 15:43:24 kls Exp $
*/
#include "dvbapi.h"
@@ -1684,9 +1684,10 @@ cDvbApi::cDvbApi(int n)
replayBuffer = NULL;
transferBuffer = NULL;
transferringFromDvbApi = NULL;
- ca = 0;
+ ca = -1;
priority = -1;
cardIndex = n;
+ SetCaCaps();
// Devices that are only present on DVB-C or DVB-S cards:
@@ -1783,37 +1784,93 @@ bool cDvbApi::SetPrimaryDvbApi(int n)
return false;
}
+int cDvbApi::CanShift(int Ca, int Priority)
+{
+ // Test whether a recording on this DVB device can be shifted to another one
+ // in order to perform a new recording with the given Ca and Priority on this device:
+ int ShiftLevel = -1; // default means this device can't be shifted
+ if (Recording()) {
+ if (ProvidesCa(Ca) // this device provides the requested Ca
+ && (Ca != this->Ca() // the requested Ca is different from the one currently used...
+ || Priority > this->Priority())) { // ...or the request comes from a higher priority
+ cDvbApi *d = NULL;
+ int Provides[MAXDVBAPI];
+ for (int i = 0; i < NumDvbApis; i++) {
+ if ((Provides[i] = dvbApi[i]->ProvidesCa(this->Ca())) != 0) { // this device is basicly able to do the job
+ if (dvbApi[i] != this) { // it is not _this_ device
+ int sl = dvbApi[i]->CanShift(this->Ca(), Priority); // this is the original Priority!
+ if (sl >= 0 && (ShiftLevel < 0 || sl < ShiftLevel)) {
+ d = dvbApi[i];
+ ShiftLevel = sl;
+ }
+ }
+ }
+ }
+ if (ShiftLevel >= 0)
+ ShiftLevel++; // adds the device's own shift
+ }
+ }
+ else if (Priority > this->Priority())
+ ShiftLevel = 0; // no shifting necessary, this device can do the job
+ return ShiftLevel;
+}
+
cDvbApi *cDvbApi::GetDvbApi(int Ca, int Priority)
{
- cDvbApi *d = NULL, *dMinPriority = NULL;
- int index = Ca - 1;
- for (int i = 0; i < MAXDVBAPI; i++) {
- if (dvbApi[i]) {
- if (dvbApi[i]->CardIndex() == index) { // means we need exactly _this_ device
+ cDvbApi *d = NULL;
+ int Provides[MAXDVBAPI];
+ // Check which devices provide Ca:
+ for (int i = 0; i < NumDvbApis; i++) {
+ if ((Provides[i] = dvbApi[i]->ProvidesCa(Ca)) != 0) { // this device is basicly able to do the job
+ if (Priority > dvbApi[i]->Priority() // Priority is high enough to use this device
+ && (!d // we don't have a device yet, or...
+ || dvbApi[i]->Priority() < d->Priority() // ...this one has an even lower Priority
+ || (dvbApi[i]->Priority() == d->Priority() // ...same Priority...
+ && Provides[i] < Provides[d->CardIndex()]))) // ...but this one provides fewer Ca values
d = dvbApi[i];
- break;
- }
- else if (Ca == 0) { // means any device would be acceptable
- if (!d || !dvbApi[i]->Recording() || (d->Recording() && d->Priority() > dvbApi[i]->Priority()))
- d = dvbApi[i]; // this is one that is either not currently recording or has the lowest priority
- if (d && d != PrimaryDvbApi && !d->Recording()) // avoids the PrimaryDvbApi if possible
- break;
- if (d && d->Recording() && d->Priority() < Setup.PrimaryLimit && (!dMinPriority || d->Priority() < dMinPriority->Priority()))
- dMinPriority = d; // this is the one with the lowest priority below Setup.PrimaryLimit
- }
}
}
- if (d == PrimaryDvbApi) { // the PrimaryDvbApi was the only one that was free
- if (Priority < Setup.PrimaryLimit)
- return NULL; // not enough priority to use the PrimaryDvbApi
- if (dMinPriority) // there's one that must not use the PrimaryDvbApi...
- d = dMinPriority; // ...so let's kick out that one
+ if (!d && Ca > MAXDVBAPI) {
+ // We didn't find one the easy way, so now we have to try harder:
+ int ShiftLevel = -1;
+ for (int i = 0; i < NumDvbApis; i++) {
+ if (Provides[i]) { // this device is basicly able to do the job, but for some reason we didn't get it above
+ int sl = dvbApi[i]->CanShift(Ca, Priority); // asks this device to shift its job to another device
+ if (sl >= 0 && (ShiftLevel < 0 || sl < ShiftLevel)) {
+ d = dvbApi[i]; // found one that can be shifted with the fewest number of subsequent shifts
+ ShiftLevel = sl;
+ }
+ }
+ }
}
- return (d // we found one...
- && (!d->Recording() // ...that's either not currently recording...
- || d->Priority() < Priority // ...or has a lower priority...
- || (!d->Ca() && Ca))) // ...or doesn't need this card
- ? d : NULL;
+ return d;
+}
+
+void cDvbApi::SetCaCaps(void)
+{
+ for (int i = 0; i < MAXCACAPS; i++)
+ caCaps[i] = Setup.CaCaps[CardIndex()][i];
+}
+
+int cDvbApi::ProvidesCa(int Ca)
+{
+ if (Ca == CardIndex() + 1)
+ return 1; // exactly _this_ card was requested
+ if (Ca && Ca <= MAXDVBAPI)
+ return 0; // a specific card was requested, but not _this_ one
+ int result = Ca ? 0 : 1; // by default every card can provide FTA
+ int others = Ca ? 1 : 0;
+ for (int i = 0; i < MAXCACAPS; i++) {
+ if (caCaps[i]) {
+ if (caCaps[i] == Ca)
+ result = 1;
+ else
+ others++;
+ }
+ else
+ break;
+ }
+ return result ? result + others : 0;
}
bool cDvbApi::Probe(const char *FileName)
@@ -1854,7 +1911,7 @@ bool cDvbApi::Init(void)
void cDvbApi::Cleanup(void)
{
- for (int i = 0; i < MAXDVBAPI; i++) {
+ for (int i = 0; i < NumDvbApis; i++) {
delete dvbApi[i];
dvbApi[i] = NULL;
}
@@ -2148,6 +2205,11 @@ void cDvbApi::Flush(void)
#endif
}
+int cDvbApi::Priority(void)
+{
+ return (this == PrimaryDvbApi && !Recording()) ? Setup.PrimaryLimit - 1 : priority;
+}
+
int cDvbApi::SetModeRecord(void)
{
// Sets up the DVB device for recording
@@ -2262,7 +2324,7 @@ eSetChannelResult cDvbApi::SetChannel(int ChannelNumber, int Frequency, char Pol
// If this card can't receive this channel, we must not actually switch
// the channel here, because that would irritate the driver when we
// start replaying in Transfer Mode immediately after switching the channel:
- bool NeedsTransferMode = (this == PrimaryDvbApi && Ca && Ca != CardIndex() + 1);
+ bool NeedsTransferMode = (this == PrimaryDvbApi && !ProvidesCa(Ca));
if (!NeedsTransferMode) {
@@ -2504,7 +2566,7 @@ void cDvbApi::StopRecord(void)
if (recordBuffer) {
delete recordBuffer;
recordBuffer = NULL;
- ca = 0;
+ ca = -1;
priority = -1;
}
}
@@ -2703,7 +2765,7 @@ void cEITScanner::Process(void)
time_t now = time(NULL);
if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) {
for (int i = 0; i < MAXDVBAPI; i++) {
- cDvbApi *DvbApi = cDvbApi::GetDvbApi(i + 1, MAXPRIORITY);
+ cDvbApi *DvbApi = cDvbApi::GetDvbApi(i + 1, MAXPRIORITY + 1);
if (DvbApi) {
if (DvbApi != cDvbApi::PrimaryDvbApi || (cDvbApi::NumDvbApis == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) {
if (!(DvbApi->Recording() || DvbApi->Replaying() || DvbApi->Transferring())) {
diff --git a/dvbapi.h b/dvbapi.h
index 06028f0b..396b5c21 100644
--- a/dvbapi.h
+++ b/dvbapi.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbapi.h 1.63 2002/02/24 12:38:08 kls Exp $
+ * $Id: dvbapi.h 1.64 2002/03/03 14:51:20 kls Exp $
*/
#ifndef __DVBAPI_H
@@ -94,12 +94,16 @@ private:
public:
~cDvbApi();
-#define MAXDVBAPI 4
+#define MAXDVBAPI 4 // the maximum number of DVB cards in the system
+#define MAXCACAPS 16 // the maximum number of different CA values per DVB card
+
static int NumDvbApis;
private:
static cDvbApi *dvbApi[MAXDVBAPI];
static int useDvbApi;
int cardIndex;
+ int caCaps[MAXCACAPS];
+ int CanShift(int Ca, int Priority);
public:
static cDvbApi *PrimaryDvbApi;
static void SetUseDvbApi(int n);
@@ -110,9 +114,10 @@ public:
// Sets the primary DVB device to 'n' (which must be in the range
// 1...NumDvbApis) and returns true if this was possible.
static cDvbApi *GetDvbApi(int Ca, int Priority);
- // Selects a free DVB device, starting with the highest device number
- // (but avoiding, if possible, the PrimaryDvbApi).
- // If Ca is not 0, the device with the given number will be returned.
+ // Selects a free DVB device, avoiding the PrimaryDvbApi if possible.
+ // If Ca is not 0, the device with the given number will be returned
+ // in case Ca is <= MAXDVBAPI, or the device that provides the given
+ // value in its caCaps.
// If all DVB devices are currently recording, the one recording the
// lowest priority timer (if any) that is lower than the given Priority
// will be returned.
@@ -120,6 +125,15 @@ public:
// recording and stop recording if necessary.
int CardIndex(void) { return cardIndex; }
// Returns the card index of this DvbApi (0 ... MAXDVBAPI - 1).
+ void SetCaCaps(void);
+ // Sets the CaCaps of this DVB device according to the Setup data.
+ int ProvidesCa(int Ca);
+ // Checks whether this DVB device provides the given value in its
+ // caCaps. Returns 0 if the value is not provided, 1 if only this
+ // value is provided, and > 1 if this and other values are provided.
+ // If the given value is equal to the number of this DVB device,
+ // 1 is returned. If it is 0 (FTA), 1 plus the number of other values
+ // in caCaps is returned.
static bool Probe(const char *FileName);
// Probes for existing DVB devices.
static bool Init(void);
@@ -204,16 +218,17 @@ private:
cPlayBuffer *replayBuffer;
int ca;
int priority;
- int Priority(void) { return priority; }
+ int Priority(void);
// Returns the priority of the current recording session (0..MAXPRIORITY),
- // or -1 if no recording is currently active.
+ // or -1 if no recording is currently active. The primary DVB device will
+ // always return at least Setup.PrimaryLimit-1.
int SetModeRecord(void);
// Initiates recording mode and returns the file handle to read from.
void SetModeReplay(void);
void SetModeNormal(bool FromRecording);
public:
int Ca(void) { return ca; }
- // Returns the ca of the current recording session (0..MAXDVBAPI).
+ // Returns the ca of the current recording session.
int SecondsToFrames(int Seconds);
// Returns the number of frames corresponding to the given number of seconds.
bool Recording(void);
diff --git a/i18n.c b/i18n.c
index 08397157..d75f3302 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.c 1.57 2002/02/24 12:54:12 kls Exp $
+ * $Id: i18n.c 1.58 2002/03/03 16:12:00 kls Exp $
*
* Slovenian translations provided by Miha Setina <mihasetina@softhome.net>
* Italian translations provided by Alberto Carraro <bertocar@tin.it>
@@ -1176,6 +1176,16 @@ const tPhrase Phrases[] = {
"", // TODO
"Näytä toiston tila",
},
+ { "CICAM DVB",
+ "CICAM DVB",
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ "", // TODO
+ },
// The days of the week:
{ "MTWTFSS",
"MDMDFSS",
diff --git a/menu.c b/menu.c
index 28e5d4d8..b1e7e49e 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.159 2002/02/24 12:55:49 kls Exp $
+ * $Id: menu.c 1.160 2002/03/03 16:12:29 kls Exp $
*/
#include "menu.h"
@@ -585,6 +585,60 @@ void cMenuEditStraItem::Set(void)
SetValue(strings[*value]);
}
+// --- cMenuEditCaItem -------------------------------------------------------
+
+class cMenuEditCaItem : public cMenuEditIntItem {
+private:
+ const cCaDefinition *ca;
+ bool allowCardNr;
+protected:
+ virtual void Set(void);
+public:
+ cMenuEditCaItem(const char *Name, int *Value, bool AllowCardNr = false);
+ eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditCaItem::cMenuEditCaItem(const char *Name, int *Value, bool AllowCardNr)
+:cMenuEditIntItem(Name, Value, 0)
+{
+ ca = CaDefinitions.Get(*Value);
+ allowCardNr = AllowCardNr;
+ Set();
+}
+
+void cMenuEditCaItem::Set(void)
+{
+ if (ca)
+ SetValue(ca->Description());
+ else
+ cMenuEditIntItem::Set();
+}
+
+eOSState cMenuEditCaItem::ProcessKey(eKeys Key)
+{
+ eOSState state = cMenuEditItem::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
+ if (ca && ca->Prev()) {
+ ca = (cCaDefinition *)ca->Prev();
+ *value = ca->Number();
+ }
+ }
+ else if (NORMALKEY(Key) == kRight) {
+ if (ca && ca->Next() && (allowCardNr || ((cCaDefinition *)ca->Next())->Number() > MAXDVBAPI)) {
+ ca = (cCaDefinition *)ca->Next();
+ *value = ca->Number();
+ }
+ }
+ else
+ return cMenuEditIntItem::ProcessKey(Key);
+ Set();
+ state = osContinue;
+ }
+ return state;
+}
+
// --- cMenuEditChannel ------------------------------------------------------
class cMenuEditChannel : public cOsdMenu {
@@ -613,7 +667,7 @@ cMenuEditChannel::cMenuEditChannel(int Index)
Add(new cMenuEditIntItem( tr("Dpid1"), &data.dpid1, 0, 0x1FFF));
Add(new cMenuEditIntItem( tr("Dpid2"), &data.dpid2, 0, 0x1FFF));
Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0x1FFF));
- Add(new cMenuEditIntItem( tr("CA"), &data.ca, 0, cDvbApi::NumDvbApis));
+ Add(new cMenuEditCaItem( tr("CA"), &data.ca, true));
Add(new cMenuEditIntItem( tr("Pnr"), &data.pnr, 0));
}
}
@@ -1880,6 +1934,13 @@ void cMenuSetup::Set(void)
Add(new cMenuEditIntItem( tr("MinUserInactivity"), &data.MinUserInactivity));
Add(new cMenuEditBoolItem(tr("MultiSpeedMode"), &data.MultiSpeedMode));
Add(new cMenuEditBoolItem(tr("ShowReplayMode"), &data.ShowReplayMode));
+ for (int d = 0; d < cDvbApi::NumDvbApis; d++) {
+ for (int i = 0; i < 2; i++) {
+ char buffer[32];
+ snprintf(buffer, sizeof(buffer), "%s%d %d", tr("CICAM DVB"), d + 1, i + 1);
+ Add(new cMenuEditCaItem(buffer, &data.CaCaps[d][i]));
+ }
+ }
}
eOSState cMenuSetup::ProcessKey(eKeys Key)
diff --git a/vdr.c b/vdr.c
index 90c1d843..a246be11 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
- * $Id: vdr.c 1.97 2002/02/24 12:55:10 kls Exp $
+ * $Id: vdr.c 1.98 2002/03/03 14:56:03 kls Exp $
*/
#include <getopt.h>
@@ -252,6 +252,7 @@ int main(int argc, char *argv[])
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf"));
Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"));
SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true);
+ CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true);
#if defined(REMOTE_LIRC)
Keys.SetDummyValues();
#elif !defined(REMOTE_NONE)