summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS6
-rw-r--r--HISTORY48
-rw-r--r--channels.c110
-rw-r--r--channels.conf87
-rw-r--r--channels.conf.cable2
-rw-r--r--channels.conf.terr51
-rw-r--r--channels.h18
-rw-r--r--config.h4
-rw-r--r--device.c4
-rw-r--r--dvbdevice.c6
-rw-r--r--eit.c128
-rw-r--r--eit.h31
-rw-r--r--i18n.c18
-rw-r--r--menu.c103
-rw-r--r--osd.c22
-rw-r--r--osd.h7
-rw-r--r--remote.h4
-rw-r--r--svdrp.c43
-rw-r--r--timers.c53
-rw-r--r--timers.h5
-rw-r--r--tools.c9
-rw-r--r--tools.h4
-rw-r--r--vdr.530
23 files changed, 484 insertions, 309 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 399ba30..6463c53 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -302,6 +302,7 @@ Mirko Günther <mi.guenther@ib-helms.de>
Achim Lange <Achim_Lange@t-online.de>
for replacing 'killproc' with 'killall' in 'runvdr' to make it work on Debian
for reporting a bug in switching back the replay mode display in time shift mode
+ for his help in keeping 'channels.conf.cable' up to date
Klaus Wolf <klaus@wolfsoft.de>
for reporting a bug in restoring the CICAM values for a fourth DVB card
@@ -441,6 +442,7 @@ Lauri Tischler <lauri.tischler@efore.fi>
Andy Carter <fruit@ukgateway.net>
for helping to test new DVB-T handling
+ for his help in keeping 'channels.conf.terr' up to date
Robert Schiele <rschiele@uni-mannheim.de>
for his help in keeping 'channels.conf.cable' up to date
@@ -460,3 +462,7 @@ Dennis Noordsij <dennis.noordsij@wiral.com>
Steffen Barszus <st_barszus@gmx.de>
for reporting a bug in switching audio tracks in 'Transfer Mode' on the primary DVB device
+
+Peter Seyringer <e9425234@student.tuwien.ac.at>
+ for reporting a bug in saving the polarization parameter of channels that have a
+ number in the 'source' parameter
diff --git a/HISTORY b/HISTORY
index dc276f5..e0a5f11 100644
--- a/HISTORY
+++ b/HISTORY
@@ -249,7 +249,7 @@ Video Disk Recorder Revision History
- The EIT information is now gathered in a separate thread.
- The sytem time can now be synchronized to the time broadcast in the DVB data
stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to
- 1. Note that this works only if VDR is running under a user id that has
+ 1. Note that this works only if VDR is running under a user ID that has
permisson to set the system time.
- The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert
Schneider). See the MANUAL file for a detailed description.
@@ -1721,3 +1721,49 @@ Video Disk Recorder Revision History
DVB_DRIVER_VERSION stuff has been replaced with DO_REC_AND_PLAY_ON_PRIMARY_DEVICE,
which can be used to disable simultaneous recording and replaying on the primary
DVB device in case there are problems with this.
+
+2002-11-10: Version 1.1.16
+
+- Fixed saving the polarization parameter of channels that have a number in the
+ 'source' parameter (thanks to Peter Seyringer for reporting this one).
+- Updated 'channels.conf.terr' (thanks to Andy Carter).
+- Updated 'channels.conf.cable' (thanks to Achim Lange).
+- First step towards a "unique channel ID". The channel ID is a human readable
+ string, made up from several parameters of the channel's definition in the file
+ 'channels.conf' (see man vdr(5) for details).
+ In order for the "unique channel ID" to work, all channel definitions now must
+ be unique with respect to the combination of their Source, Frequency and SID
+ parameters. You may have to fix your 'channels.conf' manually if there are error
+ messages in the log file when loading it. BE SURE TO MAKE A BACKUP COPY OF YOUR
+ 'channels.conf' AND 'timers.conf' FILE BEFORE SWITCHING TO THIS VERSION, AND CHECK
+ VERY CAREFULLY WHETHER YOUR TIMERS ARE STILL SET TO THE RIGHT CHANNELS!
+ When reading an existing 'timers.conf', the channels will be identified as before
+ by their numbers. As soon as this file is written back, the channel numbers will
+ be replaced by the channel IDs. After that it is possible to manually edit the
+ 'channels.conf' file and rearrange the channels without breaking the timers.
+ Note that you can still define new timers manually by using the channel number.
+ VDR will correctly identify the 'channel' parameter in a timer definition and
+ use it as a channel number or a channel ID, respectively. Also, the SVDRP commands
+ that return timer definitions will list them with channel numbers in order to
+ stay compatible with existing applications.
+ The channel ID is also used in the 'epg.data' file to allow EPG information from
+ different sources to be stored, which would previously have been mixed up in case
+ they were using the same 'service ID'. Note that the contents of an existing
+ 'epg.data' file from a previous version will be silently ignored, since it doesn't
+ contain the new channel IDs. When inserting EPG data into VDR via SVDRP you now also
+ need to use the channel IDs.
+ Currently the EPG data received from the DVB data stream only uses the 'Source'
+ and 'Service ID' part of the channel ID. This makes it work for channels with
+ the same service IDs on different sources (like satellites, cable or terrestrial).
+ However, it doesn't work yet if the service IDs are not unique within a specific
+ source. This will be fixed later.
+- Added missing SID parameters to 'channels.conf'. Some channels have been removed
+ since they are apparently no longer broadcasted.
+- Removed dropping EPG events from "other" streams that have a duration of 86400
+ seconds or more (was introduced in version 1.1.10). This has become obsolete by
+ the modification in version 1.1.13, which fixed fetching the current/next information
+ to handle cases where the duration of an event is set wrongly and would last beyond
+ the start time of the next event. Besides, the change in 1.1.10 broke handling EPG
+ data for NVOD channels.
+- Fixed a compiler warning regarding cMenuChannels::Del() and MenuTimers::Del() hiding
+ the base class virtual functions.
diff --git a/channels.c b/channels.c
index 4f1bcec..cb05e2c 100644
--- a/channels.c
+++ b/channels.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.c 1.6 2002/11/01 10:26:45 kls Exp $
+ * $Id: channels.c 1.8 2002/11/10 13:01:55 kls Exp $
*/
#include "channels.h"
@@ -126,19 +126,18 @@ char *cChannel::buffer = NULL;
cChannel::cChannel(void)
{
- *name = 0;
- frequency = 0;
- source = 0;
- srate = 0;
- vpid = 0;
- apid1 = 0;
+ strcpy(name, "Pro7");
+ frequency = 12480;
+ source = cSource::FromString("S19.2E");
+ srate = 27500;
+ vpid = 255;
+ apid1 = 256;
apid2 = 0;
- dpid1 = 0;
+ dpid1 = 257;
dpid2 = 0;
- tpid = 0;
+ tpid = 32;
ca = 0;
sid = 0;
- number = 0;
groupSep = false;
polarization = 'v';
inversion = INVERSION_AUTO;
@@ -151,30 +150,44 @@ cChannel::cChannel(void)
hierarchy = HIERARCHY_AUTO;
}
-cChannel::cChannel(const cChannel *Channel)
+cChannel& cChannel::operator= (const cChannel &Channel)
{
- strcpy(name, Channel ? Channel->name : "Pro7");
- frequency = Channel ? Channel->frequency : 12480;
- source = Channel ? Channel->source : 0;
- srate = Channel ? Channel->srate : 27500;
- vpid = Channel ? Channel->vpid : 255;
- apid1 = Channel ? Channel->apid1 : 256;
- apid2 = Channel ? Channel->apid2 : 0;
- dpid1 = Channel ? Channel->dpid1 : 257;
- dpid2 = Channel ? Channel->dpid2 : 0;
- tpid = Channel ? Channel->tpid : 32;
- ca = Channel ? Channel->ca : 0;
- sid = Channel ? Channel->sid : 0;
- groupSep = Channel ? Channel->groupSep : false;
- polarization = Channel ? Channel->polarization : 'v';
- inversion = Channel ? Channel->inversion : INVERSION_AUTO;
- bandwidth = Channel ? Channel->bandwidth : BANDWIDTH_AUTO;
- coderateH = Channel ? Channel->coderateH : FEC_AUTO;
- coderateL = Channel ? Channel->coderateL : FEC_AUTO;
- modulation = Channel ? Channel->modulation : QAM_AUTO;
- transmission = Channel ? Channel->transmission : TRANSMISSION_MODE_AUTO;
- guard = Channel ? Channel->guard : GUARD_INTERVAL_AUTO;
- hierarchy = Channel ? Channel->hierarchy : HIERARCHY_AUTO;
+ memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
+ return *this;
+}
+
+static int MHz(int frequency)
+{
+ while (frequency > 20000) {
+ frequency /= 1000;
+ }
+ return frequency;
+}
+
+uint64 cChannel::GetChannelID(void) const
+{
+ return (uint64(source) << 48) | (uint64(0) << 32) | ((MHz(frequency)) << 16) | sid;
+}
+
+const char *cChannel::GetChannelIDStr(void) const
+{
+ static char buffer[256];
+ snprintf(buffer, sizeof(buffer), "%s-%d-%d-%d", cSource::ToString(source), 0, MHz(frequency), sid);
+ return buffer;
+}
+
+uint64 cChannel::StringToChannelID(const char *s)
+{
+ char *sourcebuf = NULL;
+ int reserved;
+ int frequency;
+ int sid;
+ if (4 == sscanf(s, "%a[^-]-%d-%d-%d", &sourcebuf, &reserved, &frequency, &sid)) {
+ int source = cSource::FromString(sourcebuf);
+ if (source >= 0)
+ return (uint64(source) << 48) | (uint64(reserved) << 32) | (frequency << 16) | sid;
+ }
+ return 0;
}
static int PrintParameter(char *p, char Name, int Value)
@@ -185,6 +198,8 @@ static int PrintParameter(char *p, char Name, int Value)
const char *cChannel::ParametersToString(void)
{
char type = *cSource::ToString(source);
+ if (isdigit(type))
+ type = 'S';
#define ST(s) if (strchr(s, type))
static char buffer[64];
char *q = buffer;
@@ -276,7 +291,7 @@ const char *cChannel::ToText(void)
return ToText(this);
}
-bool cChannel::Parse(const char *s)
+bool cChannel::Parse(const char *s, bool AllowNonUniqueID)
{
if (*s == ':') {
groupSep = true;
@@ -322,6 +337,10 @@ bool cChannel::Parse(const char *s)
free(sourcebuf);
free(apidbuf);
free(namebuf);
+ if (!AllowNonUniqueID && Channels.GetByChannelID(GetChannelID())) {
+ esyslog("ERROR: channel data not unique!");
+ return false;
+ }
return ok;
}
else
@@ -402,15 +421,34 @@ cChannel *cChannels::GetByNumber(int Number, int SkipGap)
return NULL;
}
-cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
+cChannel *cChannels::GetByServiceID(int Source, unsigned short ServiceID)
+{
+ for (cChannel *channel = First(); channel; channel = Next(channel)) {
+ if (!channel->GroupSep() && channel->Source() == Source && channel->Sid() == ServiceID)
+ return channel;
+ }
+ return NULL;
+}
+
+cChannel *cChannels::GetByChannelID(uint64 ChannelID)
{
for (cChannel *channel = First(); channel; channel = Next(channel)) {
- if (!channel->GroupSep() && channel->Sid() == ServiceId)
+ if (!channel->GroupSep() && channel->GetChannelID() == ChannelID)
return channel;
}
return NULL;
}
+bool cChannels::HasUniqueChannelID(cChannel *NewChannel, cChannel *OldChannel)
+{
+ uint64 NewChannelID = NewChannel->GetChannelID();
+ for (cChannel *channel = First(); channel; channel = Next(channel)) {
+ if (!channel->GroupSep() && channel != OldChannel && channel->GetChannelID() == NewChannelID)
+ return false;
+ }
+ return true;
+}
+
bool cChannels::SwitchTo(int Number)
{
cChannel *channel = GetByNumber(Number);
diff --git a/channels.conf b/channels.conf
index da014a8..f440ca7 100644
--- a/channels.conf
+++ b/channels.conf
@@ -17,7 +17,6 @@ KiKa:11954:h:S19.2E:27500:310:320:330:0:28008
arte:11836:h:S19.2E:27500:401:402:404:0:28109
ORF1:12692:h:S19.2E:22000:160:161:165:102:13001
ORF2:12692:h:S19.2E:22000:500:501:505:102:13002
-ORF Sat:11954:h:S19.2E:27500:506:507:0:0:28010
ZDF.info:11954:h:S19.2E:27500:610:620:0:0:28011
CNN:12168:v:S19.2E:27500:165:100:0:0:28512
Super RTL:12188:h:S19.2E:27500:165:120:65:0:12040
@@ -27,13 +26,13 @@ Kabel 1:12480:v:S19.2E:27500:511:512:33:0:899
Neun Live:12480:v:S19.2E:27500:767:768:35:0:897
DSF:12480:v:S19.2E:27500:1023:1024:0:0:900
HOT:12480:v:S19.2E:27500:1279:1280:0:0:40
-Bloomberg TV Germany:12551:v:S19.2E:22000:162:99:0:0:12160
+Bloomberg TV Germany:12552:v:S19.2E:22000:162:99:0:0:12160
Bloomberg TV France:11817:v:S19.2E:27500:163:92:0:0:8004
Bloomberg TV Spain:12168:v:S19.2E:27500:167:112:0:0:12721
Sky News:12552:v:S19.2E:22000:305:306:0:0:3995
Fox Kids Netherlands:12574:h:S19.2E:22000:163:92:0:0:5020
Alice:12610:v:S19.2E:22000:162:96:0:0:12200
-n-tv:12669:v:S19.2E:22000:162:96:55:0:12730
+n-tv:12670:v:S19.2E:22000:162:96:55:0:12730
Grand Tourisme:12670:v:S19.2E:22000:289:290:0:0:17300
TW1:12692:h:S19.2E:22000:166:167:0:0:13013
Eurosport:11954:h:S19.2E:27500:410:420:0:0:28009
@@ -45,7 +44,6 @@ ZDF.doku:11954:h:S19.2E:27500:660:670:0:0:28014
MDR:12110:h:S19.2E:27500:401:402:404:0:28204
ORB:12110:h:S19.2E:27500:501:502:504:0:28205
B1:12110:h:S19.2E:27500:601:602:604:0:28206
-ARD Online-Kanal:12722:h:S19.2E:22000:0:701:0:0:0
:Premiere World
Premiere Start:11797:h:S19.2E:27500:255:256:0:101:8
Premiere 1:11797:h:S19.2E:27500:511:512,513;515:0:101:10
@@ -93,7 +91,7 @@ Premiere Sport 2:12031:h:S19.2E:27500:3839:3840:0:101:27
:#Boxengasse:12070:h:S19.2E:27500:767:768:0:101:213
:#Verfolgerfeld:12070:h:S19.2E:27500:1023:1024:0:101:214
:#Infokanal:12070:h:S19.2E:27500:1279:1280:0:101:215
-Multikanal:11720:h:S19.2E:27500:255:256:0:101:17
+:#Multikanal:11720:h:S19.2E:27500:255:256:0:101:17
:Beta Digital
N24:12480:v:S19.2E:27500:2047:2048:0:0:47
CNBC:11954:h:S19.2E:27500:510:520:0:0:28010
@@ -110,77 +108,42 @@ BuLi 7:11719:h:S19.2E:27500:3327:3328,3329:0:101:245
BuLi 8:12031:h:S19.2E:27500:3071:3072,3073:0:101:208
BuLi 9:12031:h:S19.2E:27500:3327:3328,3329:0:101:209
:-
-:#TV Niepokalanow:11876:h:S19.2E:27500:305:321:0:0:20601
Mosaico:11934:v:S19.2E:27500:165:100:0:0:29010
Andalucia TV:11934:v:S19.2E:27500:166:104:0:0:29011
-TVC Internacional:11934:v:S19.2E:27500:167:108:0:0:0
-Nasza TV:11992:h:S19.2E:27500:165:98:0:0:0
-WishLine test:12012:v:S19.2E:27500:163:90:0:0:0
+Canal J:11934:v:S19.2E:27500:167:108:0:0:8157
+Extreme Sports Channel:11992:h:S19.2E:27500:165:98,99:0:0:20365
Pro 7 Austria:12051:v:S19.2E:27500:161:84:0:0:20002
Kabel 1 Schweiz:12051:v:S19.2E:27500:162:163:0:0:20003
Kabel 1 Austria:12051:v:S19.2E:27500:166:167:0:0:20004
Pro 7 Schweiz:12051:v:S19.2E:27500:289:290:0:0:20001
-Kiosque:12129:v:S19.2E:27500:160:80:0:0:0
KTO:11739:v:S19.2E:27500:163:90:0:0:8304
-TCM:12168:v:S19.2E:27500:160:80:0:0:0
-Cartoon Network France & Spain:12168:v:S19.2E:27500:161:84:0:0:0
-TVBS Europe:12168:v:S19.2E:27500:162:88:0:0:0
-TVBS Europe:12168:v:S19.2E:27500:162:89:0:0:0
-Travel:12168:v:S19.2E:27500:163:92:0:0:0
-TCM Espania:12168:v:S19.2E:27500:164:96:0:0:0
-MTV Spain:12168:v:S19.2E:27500:167:112:0:0:0
-TCM France:12168:v:S19.2E:27500:169:64:0:0:0
-RTL2 CH:12188:h:S19.2E:27500:164:112:0:0:0
+Cartoon Network France:12168:v:S19.2E:27500:161:84:0:0:28511
+TVBS Europe:12168:v:S19.2E:27500:162:88,89:0:0:28631
+travel channel:12168:v:S19.2E:27500:163:92,93:0:0:28001
+TCM Espana:12168:v:S19.2E:27500:164:96,97:0:0:28516
+TCM France:12168:v:S19.2E:27500:169:64,65:0:0:28515
La Cinquieme:12207:v:S19.2E:27500:160:80:0:0:8501
LCP:12207:v:S19.2E:27500:165:100:0:0:8506
-Post Filial TV:12226:h:S19.2E:27500:255:256:0:0:0
-Canal Canaris:12246:v:S19.2E:27500:160:80:0:0:0
-Canal Canaris:12246:v:S19.2E:27500:160:81:0:0:0
-Canal Canaris:12246:v:S19.2E:27500:160:82:0:0:0
-Canal Canaris:12246:v:S19.2E:27500:160:83:0:0:0
AB Moteurs:12266:h:S19.2E:27500:160:80:0:0:17000
-AB Channel 1:12266:h:S19.2E:27500:161:84:0:0:0
-Taquilla 0:12285:v:S19.2E:27500:165:100:0:0:0
-CSAT:12324:v:S19.2E:27500:160:80:0:0:0
-Mosaique:12324:v:S19.2E:27500:162:88:0:0:0
-Mosaique 2:12324:v:S19.2E:27500:163:92:0:0:0
-Mosaique 3:12324:v:S19.2E:27500:164:96:0:0:0
-Le Sesame C+:12324:v:S19.2E:27500:165:1965:0:0:0
-FEED:12344:h:S19.2E:27500:163:92:0:0:0
-RTM 1:12363:v:S19.2E:27500:162:96:0:0:0
-ESC 1:12363:v:S19.2E:27500:163:104:0:0:0
-TV5 Europe:12363:v:S19.2E:27500:164:112:0:0:0
-TV7 Tunisia:12363:v:S19.2E:27500:166:128:0:0:0
-ARTE:12363:v:S19.2E:27500:167:137:0:0:0
+AB 1:12266:h:S19.2E:27500:161:84:0:0:17001
+Escales:12285:v:S19.2E:27500:165:100:0:0:17025
+Canal Club:12324:v:S19.2E:27500:160:80:0:0:8612
RAI Uno:10788:v:S19.2E:22000:289:290:0:0:9004
-RTP International:12363:v:S19.2E:27500:300:301:0:0:0
-Fashion TV:12402:v:S19.2E:27500:163:92:0:0:0
-VideoService:12422:h:S19.2E:27500:255:256:0:0:0
-Beta Research promo:12422:h:S19.2E:27500:1023:1024:0:0:0
-Canal Canarias:12441:v:S19.2E:27500:160:80:0:0:0
-Fitur:12441:v:S19.2E:27500:514:662:0:0:0
-Astra Info 1:12552:v:S19.2E:22000:164:112:0:0:0
-Astra Info 2:12552:v:S19.2E:22000:165:120:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:144:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:145:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:146:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:147:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:148:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:149:0:0:0
-Astra Vision 1:12552:v:S19.2E:22000:168:150:0:0:0
+K13:12402:v:S19.2E:27500:163:92:0:0:8704
+Astra Mosaic 1:12552:v:S19.2E:22000:175:176:0:0:3988
+Astra Mosaic 2:12552:v:S19.2E:22000:179:120:0:0:3987
+Astra Mosaic 3:12552:v:S19.2E:22000:182:169:0:0:3986
+Astra Mosaic 4:12552:v:S19.2E:22000:185:170:0:0:3985
+Astra Mosaic 5:12552:v:S19.2E:22000:163:170:0:0:3984
+Chamber TV:12552:v:S19.2E:22000:55:56:0:0:12180
RTL Tele Letzebuerg:12552:v:S19.2E:22000:168:144,146:0:0:3994
-Astra Mosaic:12552:v:S19.2E:22000:175:176:0:0:0
-MHP test:12604:h:S19.2E:22000:5632:0:0:0:0
VERONICA:12574:h:S19.2E:22000:161:84:0:0:5010
-VH1 Classic:12699:v:S19.2E:22000:3071:3072:0:0:28647
-MTV 2 Pop:12699:v:S19.2E:22000:3081:3082:0:0:28648
+VH1 Classic:12670:v:S19.2E:22000:3071:3072:0:0:28647
+MTV 2 Pop:12670:v:S19.2E:22000:3081:3082:0:0:28648
Via 1 - Schöner Reisen:12148:h:S19.2E:27500:511:512:0:0:44
Video Italia:12610:v:S19.2E:22000:121:122:0:0:12220
-AC 3 promo:12670:v:S19.2E:22000:308:256:0:0:0
-ORF/ZDF:12699:h:S19.2E:22000:506:507:0:0:13012
+ORF/ZDF:12670:h:S19.2E:22000:506:507:0:0:13012
VIVA:12670:v:S19.2E:22000:309:310:0:0:12732
-VIVA2:12552:v:S19.2E:22000:171:172:0:0:12120
-MTV German:12699:v:S19.2E:22000:3031:3032:0:0:28643
-:#IFA-TV:10832:h:S19.2E:22000:132:133:32:0:7251
+VIVA PLUS:12552:v:S19.2E:22000:171:172:0:0:12120
+MTV German:12670:v:S19.2E:22000:3031:3032:0:0:28643
QVC Germany:12552:v:S19.2E:22000:165:166:0:0:12100
-:#TANGOTV:10832:h:S19.2E:22000:61:62:0:0:61920
diff --git a/channels.conf.cable b/channels.conf.cable
index 14d9200..131208f 100644
--- a/channels.conf.cable
+++ b/channels.conf.cable
@@ -190,7 +190,7 @@ JAZZ:378:M64:C:6900:1:640:0:101:148
KLASSIK POPULÄR:378:M64:C:6900:1:624:0:101:147
ORCHESTRALE WERKE:378:M64:C:6900:1:560:0:101:158
CLASSIC ROCK:370:M64:C:6900:1:352:0:101:163
-VOLKSMUSIK:370:M64:C:6900:1:400:0:101:157
+CHILLOUT:370:M64:C:6900:1:400:0:101:157
SCHLAGER:370:M64:C:6900:1:384:0:101:162
GOLD:370:M64:C:6900:1:320:0:101:166
OLD GOLD:362:M64:C:6900:1:336:0:101:167
diff --git a/channels.conf.terr b/channels.conf.terr
index 62b110c..4187e11 100644
--- a/channels.conf.terr
+++ b/channels.conf.terr
@@ -1,14 +1,43 @@
-: UK channels
-BBC ONE:505833:0:0:0:600:601:0:0:4164
-BBC TWO:505833:0:0:0:610:611:0:0:4228
-ITV 1:481833:0:0:0:512:650:0:0:8261
-Channel 4:481833:0:0:0:2827:2828:0:0:8384
-Channel 5:561833:0:0:0:6017:6018:0:0:12866
-ITV 2:481833:0:0:0:2818:2819:0:0:8325
-BBC CHOICE:505833:0:0:0:620:621:0:0:4351
-BBC NEWS 24:505833:0:0:0:640:641:0:0:4415
-BBC Knowledge:505833:0:0:0:630:631:0:0:4607
-Shop!:561833:0:0:0:6049:6050:0:0:13120
+: UK channels for Crystal Palace, London
+BBC ONE (TV):505833:I0C34D0M16B8T2G32Y0:T:27500:600:601,602:602:0:4164
+BBC TWO (TV):505833:I0C34D0M16B8T2G32Y0:T:27500:610:611,612:0:2:4228
+BBC THREE (TV):505833:I0C34D0M16B8T2G32Y0:T:27500:620:621,622:0:0:4351
+BBC NEWS 24 (TV):505833:I0C34D0M16B8T2G32Y0:T:27500:640:641:0:0:4415
+Ch 14 (TV):481833:I0C23D0M64B8T2G32Y0:T:27500:2840:2841,2843:0:0:8800
+ITV 2 (TV):481833:I0C23D0M64B8T2G32Y0:T:27500:2818:2819,2821:0:0:8325
+ITV 1 (TV):481833:I0C23D0M64B8T2G32Y0:T:27500:512:650,660:0:0:8261
+Channel 4 (TV):481833:I0C23D0M64B8T2G32Y0:T:27500:2827:2828,2830:0:0:8384
+five (TV):561833:I0C23D0M64B8T2G32Y0:T:27500:6017:6018,6019:0:0:12866
+QVC (TV):561833:I0C23D0M64B8T2G32Y0:T:27500:6049:6050:0:0:13120
+TV Travel Shop (TV):561833:I0C23D0M64B8T2G32Y0:T:27500:6161:6162:0:0:13632
+ITV News (TV):561833:I0C23D0M64B8T2G32Y0:T:27500:6193:6194:0:0:13760
+BBC PARLMNT (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:403:0:0:16768
+BBC FOUR (TV):529833:I0C34D0M16B8T2G32Y0:T:27500:201:401,402:0:0:16832
+BBC R5 Live (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:430:0:0:17920
+BBC 5L SportsX (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:431:0:0:17984
+BBC 6 Music (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:432:0:0:18048
+BBC 7 (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:433:0:0:18112
+1Xtra BBC (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:434:0:0:18176
+BBC Asian Net. (RADIO):529833:I0C34D0M16B8T2G32Y0:T:27500:0:435:0:0:18240
+701 (TV):529833:I0C34D0M16B8T2G32Y0:T:27500:203:407:0:0:19456
+702 (TV):529833:I0C34D0M16B8T2G32Y0:T:27500:204:411:0:0:19520
+Sky News (TV):578166:I0C34D0M16B8T2G32Y0:T:27500:101:102,104:0:0:22080
+Sky Spts News (TV):578166:I0C34D0M16B8T2G32Y0:T:27500:201:202,204:0:0:22144
+Sky Travel (TV):578166:I0C34D0M16B8T2G32Y0:T:27500:301:302,304:0:0:22208
+UKHistory (TV):578166:I0C34D0M16B8T2G32Y0:T:27500:401:402,404:0:0:22272
+THE HITS (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:101:102:0:0:25664
+TMF (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:201:202,204:0:0:25728
+UKHomeStyle (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:301:302,306:0:0:25792
+f tn (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:301:302,304:0:0:25856
+Ch 44 (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:501:502,504:0:0:26048
+Smash Hits! (RADIO):537833:I0C34D0M16B8T2G32Y0:T:27500:0:1201:0:0:26240
+KISS (RADIO):537833:I0C34D0M16B8T2G32Y0:T:27500:0:1101:0:0:26176
+Kerrang! (RADIO):537833:I0C34D0M16B8T2G32Y0:T:27500:0:1301:0:0:26304
+jazz fm (RADIO):537833:I0C34D0M16B8T2G32Y0:T:27500:0:1401:0:0:26368
+oneword (RADIO):537833:I0C34D0M16B8T2G32Y0:T:27500:0:1501:0:0:26432
+BBC World Sv (RADIO):537833:I0C34D0M16B8T2G32Y0:T:27500:0:1601:0:0:26496
+Ch 22 (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:501:502,504:0:0:26048
+Ch 32 (TV):537833:I0C34D0M16B8T2G32Y0:T:27500:501:502,504:0:0:25984
: DVB-T Berlin Germany
PRO 7:658000:I0C23D0M16B8T8G8Y0:T:27500:305:306;307:0:0:16403
SAT 1:658000:I0C23D0M16B8T8G8Y0:T:27500:385:386:0:0:16408
diff --git a/channels.h b/channels.h
index 7eb818c..52e79b4 100644
--- a/channels.h
+++ b/channels.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.h 1.3 2002/10/20 11:50:36 kls Exp $
+ * $Id: channels.h 1.4 2002/11/10 13:01:23 kls Exp $
*/
#ifndef __CHANNELS_H
@@ -41,6 +41,7 @@ private:
static char *buffer;
static const char *ToText(cChannel *Channel);
enum { MaxChannelName = 32 }; // 31 chars + terminating 0!
+ int __BeginData__;
char name[MaxChannelName];
int frequency; // MHz
int source;
@@ -53,7 +54,6 @@ private:
int sid;
int number; // Sequence number assigned on load
bool groupSep;
- //XXX
char polarization;
int inversion;
int bandwidth;
@@ -63,13 +63,14 @@ private:
int transmission;
int guard;
int hierarchy;
+ int __EndData__;
const char *ParametersToString(void);
bool StringToParameters(const char *s);
public:
cChannel(void);
- cChannel(const cChannel *Channel);
+ cChannel& operator= (const cChannel &Channel);
const char *ToText(void);
- bool Parse(const char *s);
+ bool Parse(const char *s, bool AllowNonUniqueID = false);
bool Save(FILE *f);
const char *Name(void) const { return name; }
int Frequency(void) const { return frequency; }
@@ -86,7 +87,6 @@ public:
int Number(void) const { return number; }
void SetNumber(int Number) { number = Number; }
bool GroupSep(void) const { return groupSep; }
- //XXX
char Polarization(void) const { return polarization; }
int Inversion(void) const { return inversion; }
int Bandwidth(void) const { return bandwidth; }
@@ -96,10 +96,12 @@ public:
int Transmission(void) const { return transmission; }
int Guard(void) const { return guard; }
int Hierarchy(void) const { return hierarchy; }
- //XXX
bool IsCable(void) { return (source & cSource::st_Mask) == cSource::stCable; }
bool IsSat(void) { return (source & cSource::st_Mask) == cSource::stSat; }
bool IsTerr(void) { return (source & cSource::st_Mask) == cSource::stTerr; }
+ uint64 GetChannelID(void) const;
+ const char *GetChannelIDStr(void) const;
+ static uint64 StringToChannelID(const char *s);
};
class cChannels : public cConfig<cChannel> {
@@ -113,7 +115,9 @@ public:
int GetNextNormal(int Idx); // Get next normal channel (not group)
void ReNumber(void); // Recalculate 'number' based on channel type
cChannel *GetByNumber(int Number, int SkipGap = 0);
- cChannel *GetByServiceID(unsigned short ServiceId);
+ cChannel *GetByServiceID(int Source, unsigned short ServiceID);
+ cChannel *GetByChannelID(uint64 ChannelID);
+ bool HasUniqueChannelID(cChannel *NewChannel, cChannel *OldChannel = NULL);
bool SwitchTo(int Number);
int MaxNumber(void) { return maxNumber; }
};
diff --git a/config.h b/config.h
index 22eb9ec..af8d92b 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.138 2002/11/01 09:27:17 kls Exp $
+ * $Id: config.h 1.139 2002/11/08 13:16:12 kls Exp $
*/
#ifndef __CONFIG_H
@@ -20,7 +20,7 @@
#include "eit.h"
#include "tools.h"
-#define VDRVERSION "1.1.15"
+#define VDRVERSION "1.1.16"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/device.c b/device.c
index 69178a9..edbf5ca 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.34 2002/11/03 11:51:24 kls Exp $
+ * $Id: device.c 1.35 2002/11/10 10:17:57 kls Exp $
*/
#include "device.h"
@@ -379,7 +379,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (Result == scrOk) {
if (LiveView && IsPrimaryDevice()) {
- cSIProcessor::SetCurrentServiceID(Channel->Sid());
+ cSIProcessor::SetCurrentChannelID(Channel->GetChannelID());
currentChannel = Channel->Number();
}
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
diff --git a/dvbdevice.c b/dvbdevice.c
index 30d5658..119a28e 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 1.34 2002/11/03 12:31:11 kls Exp $
+ * $Id: dvbdevice.c 1.35 2002/11/10 12:57:17 kls Exp $
*/
#include "dvbdevice.h"
@@ -412,7 +412,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
// Stop setting system time:
if (siProcessor)
- siProcessor->SetCurrentTransponder(0);
+ siProcessor->SetCurrentTransponder(0, 0);
// Turn off live PIDs if necessary:
@@ -585,7 +585,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
// Start setting system time:
if (siProcessor)
- siProcessor->SetCurrentTransponder(Channel->Frequency());
+ siProcessor->SetCurrentTransponder(Channel->Source(), Channel->Frequency());
return true;
}
diff --git a/eit.c b/eit.c
index 12045d6..f8b436c 100644
--- a/eit.c
+++ b/eit.c
@@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.c 1.59 2002/11/02 12:46:53 kls Exp $
+ * $Id: eit.c 1.60 2002/11/10 15:50:21 kls Exp $
***************************************************************************/
#include "eit.h"
@@ -180,7 +180,7 @@ bool cTDT::SetSystemTime()
// --- cEventInfo ------------------------------------------------------------
-cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid)
+cEventInfo::cEventInfo(uint64 channelid, unsigned short eventid)
{
pTitle = NULL;
pSubtitle = NULL;
@@ -190,7 +190,7 @@ cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid)
tTime = 0;
uTableID = 0;
uEventID = eventid;
- uServiceID = serviceid;
+ uChannelID = channelid;
nChannelNumber = 0;
}
@@ -325,15 +325,15 @@ void cEventInfo::SetEventID(unsigned short evid)
uEventID = evid;
}
/** */
-void cEventInfo::SetServiceID(unsigned short servid)
+void cEventInfo::SetChannelID(uint64 channelid)
{
- uServiceID = servid;
+ uChannelID = channelid;
}
/** */
-unsigned short cEventInfo::GetServiceID() const
+uint64 cEventInfo::GetChannelID() const
{
- return uServiceID;
+ return uChannelID;
}
/** */
@@ -368,7 +368,7 @@ bool cEventInfo::Read(FILE *f, cSchedule *Schedule)
if (n == 3 || n == 4) {
pEvent = (cEventInfo *)Schedule->GetEvent(uEventID, tTime);
if (!pEvent)
- pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetServiceID(), uEventID));
+ pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetChannelID(), uEventID));
if (pEvent) {
pEvent->SetTableID(uTableID);
pEvent->SetTime(tTime);
@@ -404,24 +404,24 @@ bool cEventInfo::Read(FILE *f, cSchedule *Schedule)
struct tEpgBugFixStats {
int hits;
int n;
- unsigned short serviceIDs[MAXEPGBUGFIXCHANS];
+ uint64 channelIDs[MAXEPGBUGFIXCHANS];
tEpgBugFixStats(void) { hits = n = 0; }
};
tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS];
-static void EpgBugFixStat(int Number, unsigned int ServiceID)
+static void EpgBugFixStat(int Number, uint64 ChannelID)
{
if (0 <= Number && Number < MAXEPGBUGFIXSTATS) {
tEpgBugFixStats *p = &EpgBugFixStats[Number];
p->hits++;
int i = 0;
for (; i < p->n; i++) {
- if (p->serviceIDs[i] == ServiceID)
+ if (p->channelIDs[i] == ChannelID)
break;
}
if (i == p->n && p->n < MAXEPGBUGFIXCHANS)
- p->serviceIDs[p->n++] = ServiceID;
+ p->channelIDs[p->n++] = ChannelID;
}
}
@@ -448,7 +448,7 @@ static void ReportEpgBugFixStats(bool Reset = false)
char *q = buffer;
q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits);
for (int c = 0; c < p->n; c++) {
- cChannel *channel = Channels.GetByServiceID(p->serviceIDs[c]);
+ cChannel *channel = Channels.GetByChannelID(p->channelIDs[c]);
if (channel) {
q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name());
delim = ", ";
@@ -499,7 +499,7 @@ void cEventInfo::FixEpgBugs(void)
char *s = e ? strdup(e) : NULL;
free(pSubtitle);
pSubtitle = s;
- EpgBugFixStat(0, GetServiceID());
+ EpgBugFixStat(0, GetChannelID());
// now the fixes #1 and #2 below will handle the rest
}
}
@@ -524,7 +524,7 @@ void cEventInfo::FixEpgBugs(void)
free(pExtendedDescription);
pSubtitle = s;
pExtendedDescription = d;
- EpgBugFixStat(1, GetServiceID());
+ EpgBugFixStat(1, GetChannelID());
}
}
}
@@ -541,7 +541,7 @@ void cEventInfo::FixEpgBugs(void)
memmove(pSubtitle, pSubtitle + 1, strlen(pSubtitle));
pExtendedDescription = pSubtitle;
pSubtitle = NULL;
- EpgBugFixStat(2, GetServiceID());
+ EpgBugFixStat(2, GetChannelID());
}
}
@@ -553,7 +553,7 @@ void cEventInfo::FixEpgBugs(void)
if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) {
free(pSubtitle);
pSubtitle = NULL;
- EpgBugFixStat(3, GetServiceID());
+ EpgBugFixStat(3, GetChannelID());
}
// ZDF.info puts the Subtitle between double quotes, which is nothing
@@ -569,7 +569,7 @@ void cEventInfo::FixEpgBugs(void)
char *p = strrchr(pSubtitle, '"');
if (p)
*p = 0;
- EpgBugFixStat(4, GetServiceID());
+ EpgBugFixStat(4, GetChannelID());
}
}
@@ -590,7 +590,7 @@ void cEventInfo::FixEpgBugs(void)
if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) {
if (!startswith(p + 2, "und ")) { // special case in German, as in "Lach- und Sachgeschichten"
memmove(p, p + 2, strlen(p + 2) + 1);
- EpgBugFixStat(5, GetServiceID());
+ EpgBugFixStat(5, GetChannelID());
}
}
p++;
@@ -608,10 +608,10 @@ void cEventInfo::FixEpgBugs(void)
// --- cSchedule -------------------------------------------------------------
-cSchedule::cSchedule(unsigned short servid)
+cSchedule::cSchedule(uint64 channelid)
{
pPresent = pFollowing = NULL;
- uServiceID = servid;
+ uChannelID = channelid;
}
@@ -645,14 +645,14 @@ const cEventInfo *cSchedule::GetFollowingEvent(void) const
return pe;
}
-void cSchedule::SetServiceID(unsigned short servid)
+void cSchedule::SetChannelID(uint64 channelid)
{
- uServiceID = servid;
+ uChannelID = channelid;
}
/** */
-unsigned short cSchedule::GetServiceID() const
+uint64 cSchedule::GetChannelID() const
{
- return uServiceID;
+ return uChannelID;
}
/** */
const cEventInfo * cSchedule::GetEvent(unsigned short uEventID, time_t tTime) const
@@ -735,10 +735,10 @@ void cSchedule::Cleanup(time_t tTime)
/** */
void cSchedule::Dump(FILE *f, const char *Prefix) const
{
- cChannel *channel = Channels.GetByServiceID(uServiceID);
+ cChannel *channel = Channels.GetByChannelID(uChannelID);
if (channel)
{
- fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->Name());
+ fprintf(f, "%sC %s %s\n", Prefix, channel->GetChannelIDStr(), channel->Name());
for (cEventInfo *p = Events.First(); p; p = Events.Next(p))
p->Dump(f, Prefix);
fprintf(f, "%sc\n", Prefix);
@@ -751,12 +751,22 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
char *s;
while ((s = readline(f)) != NULL) {
if (*s == 'C') {
- unsigned int uServiceID;
- if (1 == sscanf(s + 1, "%u", &uServiceID)) {
- cSchedule *p = (cSchedule *)Schedules->AddServiceID(uServiceID);
- if (p) {
- if (!cEventInfo::Read(f, p))
- return false;
+ s = skipspace(s + 1);
+ char *p = strchr(s, ' ');
+ if (p)
+ *p = 0; // strips optional channel name
+ if (*s) {
+ uint64 uChannelID = cChannel::StringToChannelID(s);
+ if (uChannelID) {
+ cSchedule *p = (cSchedule *)Schedules->AddChannelID(uChannelID);
+ if (p) {
+ if (!cEventInfo::Read(f, p))
+ return false;
+ }
+ }
+ else {
+ esyslog("ERROR: illegal channel ID: %s", s);
+ return false;
}
}
}
@@ -775,28 +785,28 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
cSchedules::cSchedules()
{
pCurrentSchedule = NULL;
- uCurrentServiceID = 0;
+ uCurrentChannelID = 0;
}
cSchedules::~cSchedules()
{
}
/** */
-const cSchedule *cSchedules::AddServiceID(unsigned short servid)
+const cSchedule *cSchedules::AddChannelID(uint64 channelid)
{
- const cSchedule *p = GetSchedule(servid);
+ const cSchedule *p = GetSchedule(channelid);
if (!p) {
- Add(new cSchedule(servid));
- p = GetSchedule(servid);
+ Add(new cSchedule(channelid));
+ p = GetSchedule(channelid);
}
return p;
}
/** */
-const cSchedule *cSchedules::SetCurrentServiceID(unsigned short servid)
+const cSchedule *cSchedules::SetCurrentChannelID(uint64 channelid)
{
- pCurrentSchedule = AddServiceID(servid);
+ pCurrentSchedule = AddChannelID(channelid);
if (pCurrentSchedule)
- uCurrentServiceID = servid;
+ uCurrentChannelID = channelid;
return pCurrentSchedule;
}
/** */
@@ -805,14 +815,14 @@ const cSchedule * cSchedules::GetSchedule() const
return pCurrentSchedule;
}
/** */
-const cSchedule * cSchedules::GetSchedule(unsigned short servid) const
+const cSchedule * cSchedules::GetSchedule(uint64 channelid) const
{
cSchedule *p;
p = First();
while (p != NULL)
{
- if (p->GetServiceID() == servid)
+ if (p->GetChannelID() == channelid)
return p;
p = Next(p);
}
@@ -856,7 +866,7 @@ public:
cEIT(unsigned char *buf, int length, cSchedules *Schedules);
~cEIT();
/** */
- int ProcessEIT(unsigned char *buffer);
+ int ProcessEIT(unsigned char *buffer, int CurrentSource);
protected: // Protected methods
/** returns true if this EIT covers a
@@ -879,7 +889,7 @@ cEIT::~cEIT()
}
/** */
-int cEIT::ProcessEIT(unsigned char *buffer)
+int cEIT::ProcessEIT(unsigned char *buffer, int CurrentSource)
{
cEventInfo *pEvent, *rEvent = NULL;
cSchedule *pSchedule, *rSchedule = NULL;
@@ -893,18 +903,19 @@ int cEIT::ProcessEIT(unsigned char *buffer)
if (VdrProgramInfos) {
for (VdrProgramInfo = (struct VdrProgramInfo *) VdrProgramInfos->Head; VdrProgramInfo; VdrProgramInfo = (struct VdrProgramInfo *) xSucc (VdrProgramInfo)) {
- // Drop events that belong to an "other TS" and are very long (some stations broadcast bogus data for "other" channels):
- if (VdrProgramInfo->Duration >= 86400 && (tid == 0x4F || tid == 0x60 || tid == 0x61))
- continue;
- pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID);
+ //XXX TODO use complete channel ID
+ cChannel *channel = Channels.GetByServiceID(CurrentSource, VdrProgramInfo->ServiceID);
+ uint64 channelID = channel ? channel->GetChannelID() : (uint64(CurrentSource) << 48) | VdrProgramInfo->ServiceID;
+ //XXX
+ pSchedule = (cSchedule *)schedules->GetSchedule(channelID);
if (!pSchedule) {
- schedules->Add(new cSchedule(VdrProgramInfo->ServiceID));
- pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID);
+ schedules->Add(new cSchedule(channelID));
+ pSchedule = (cSchedule *)schedules->GetSchedule(channelID);
if (!pSchedule)
break;
}
if (VdrProgramInfo->ReferenceServiceID) {
- rSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ReferenceServiceID);
+ rSchedule = (cSchedule *)schedules->GetSchedule((uint64(CurrentSource) << 48) | VdrProgramInfo->ReferenceServiceID);
if (!rSchedule)
break;
rEvent = (cEventInfo *)rSchedule->GetEvent((unsigned short)VdrProgramInfo->ReferenceEventID);
@@ -915,7 +926,7 @@ int cEIT::ProcessEIT(unsigned char *buffer)
if (!pEvent) {
// If we don't have that event ID yet, we create a new one.
// Otherwise we copy the information into the existing event anyway, because the data might have changed.
- pEvent = pSchedule->AddEvent(new cEventInfo(VdrProgramInfo->ServiceID, VdrProgramInfo->EventID));
+ pEvent = pSchedule->AddEvent(new cEventInfo(channelID, VdrProgramInfo->EventID));
if (!pEvent)
break;
pEvent->SetTableID(tid);
@@ -988,6 +999,8 @@ cSIProcessor::cSIProcessor(const char *FileName)
{
fileName = strdup(FileName);
masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master'
+ currentSource = 0;
+ currentTransponder = 0;
filters = NULL;
if (!numSIProcessors++) // the first one creates it
schedules = new cSchedules;
@@ -1167,7 +1180,7 @@ void cSIProcessor::Action()
{
cMutexLock MutexLock(&schedulesMutex);
cEIT ceit(buf, seclen, schedules);
- ceit.ProcessEIT(buf);
+ ceit.ProcessEIT(buf, currentSource);
}
else
dsyslog("Received stuffing section in EIT\n");
@@ -1250,16 +1263,17 @@ bool cSIProcessor::ShutDownFilters(void)
}
/** */
-void cSIProcessor::SetCurrentTransponder(int CurrentTransponder)
+void cSIProcessor::SetCurrentTransponder(int CurrentSource, int CurrentTransponder)
{
+ currentSource = CurrentSource;
currentTransponder = CurrentTransponder;
}
/** */
-bool cSIProcessor::SetCurrentServiceID(unsigned short servid)
+bool cSIProcessor::SetCurrentChannelID(uint64 channelid)
{
cMutexLock MutexLock(&schedulesMutex);
- return schedules ? schedules->SetCurrentServiceID(servid) : false;
+ return schedules ? schedules->SetCurrentChannelID(channelid) : false;
}
void cSIProcessor::TriggerDump(void)
diff --git a/eit.h b/eit.h
index 5374003..d906725 100644
--- a/eit.h
+++ b/eit.h
@@ -16,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.h 1.20 2002/11/02 12:36:36 kls Exp $
+ * $Id: eit.h 1.21 2002/11/10 12:58:27 kls Exp $
***************************************************************************/
#ifndef __EIT_H
@@ -32,7 +32,7 @@ class cEventInfo : public cListObject {
friend class cEIT;
private:
unsigned char uTableID; // Table ID this event came from
- unsigned short uServiceID; // Service ID of program for that event
+ uint64 uChannelID; // Channel ID of program for that event
bool bIsFollowing; // true if this is the next event on this channel
bool bIsPresent; // true if this is the present event running
char *pExtendedDescription; // Extended description of this event
@@ -47,13 +47,13 @@ protected:
void SetFollowing(bool foll);
void SetPresent(bool pres);
void SetTitle(const char *string);
- void SetServiceID(unsigned short servid);
+ void SetChannelID(uint64 channelid);
void SetEventID(unsigned short evid);
void SetDuration(long l);
void SetTime(time_t t);
void SetExtendedDescription(const char *string);
void SetSubtitle(const char *string);
- cEventInfo(unsigned short serviceid, unsigned short eventid);
+ cEventInfo(uint64 channelid, unsigned short eventid);
public:
~cEventInfo();
const unsigned char GetTableID(void) const;
@@ -68,7 +68,7 @@ public:
unsigned short GetEventID(void) const;
long GetDuration(void) const;
time_t GetTime(void) const;
- unsigned short GetServiceID(void) const;
+ uint64 GetChannelID(void) const;
int GetChannelNumber(void) const { return nChannelNumber; }
void SetChannelNumber(int ChannelNumber) const { ((cEventInfo *)this)->nChannelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const'
void Dump(FILE *f, const char *Prefix = "") const;
@@ -82,21 +82,21 @@ class cSchedule : public cListObject {
private:
cEventInfo *pPresent;
cEventInfo *pFollowing;
- unsigned short uServiceID;
+ uint64 uChannelID;
cList<cEventInfo> Events;
protected:
- void SetServiceID(unsigned short servid);
+ void SetChannelID(uint64 channelid);
bool SetFollowingEvent(cEventInfo *pEvent);
bool SetPresentEvent(cEventInfo *pEvent);
void Cleanup(time_t tTime);
void Cleanup(void);
- cSchedule(unsigned short servid = 0);
+ cSchedule(uint64 channelid = 0);
public:
~cSchedule();
cEventInfo *AddEvent(cEventInfo *EventInfo);
const cEventInfo *GetPresentEvent(void) const;
const cEventInfo *GetFollowingEvent(void) const;
- unsigned short GetServiceID(void) const;
+ uint64 GetChannelID(void) const;
const cEventInfo *GetEvent(unsigned short uEventID, time_t tTime = 0) const;
const cEventInfo *GetEventAround(time_t tTime) const;
const cEventInfo *GetEventNumber(int n) const { return Events.Get(n); }
@@ -110,15 +110,15 @@ class cSchedules : public cList<cSchedule> {
friend class cSIProcessor;
private:
const cSchedule *pCurrentSchedule;
- unsigned short uCurrentServiceID;
+ uint64 uCurrentChannelID;
protected:
- const cSchedule *AddServiceID(unsigned short servid);
- const cSchedule *SetCurrentServiceID(unsigned short servid);
+ const cSchedule *AddChannelID(uint64 channelid);
+ const cSchedule *SetCurrentChannelID(uint64 channelid);
void Cleanup();
public:
cSchedules(void);
~cSchedules();
- const cSchedule *GetSchedule(unsigned short servid) const;
+ const cSchedule *GetSchedule(uint64 channelid) const;
const cSchedule *GetSchedule(void) const;
void Dump(FILE *f, const char *Prefix = "") const;
static bool Read(FILE *f);
@@ -141,6 +141,7 @@ private:
static const char *epgDataFileName;
static time_t lastDump;
bool masterSIProcessor;
+ int currentSource;
int currentTransponder;
SIP_FILTER *filters;
char *fileName;
@@ -160,8 +161,8 @@ public:
static bool Read(FILE *f = NULL);
static void Clear(void);
void SetStatus(bool On);
- void SetCurrentTransponder(int CurrentTransponder);
- static bool SetCurrentServiceID(unsigned short servid);
+ void SetCurrentTransponder(int CurrentSource, int CurrentTransponder);
+ static bool SetCurrentChannelID(uint64 channelid);
static void TriggerDump(void);
};
diff --git a/i18n.c b/i18n.c
index 08b2765..79fa607 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.99 2002/10/27 14:24:00 kls Exp $
+ * $Id: i18n.c 1.100 2002/11/10 12:32:30 kls Exp $
*
* Translations provided by:
*
@@ -1468,6 +1468,22 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"",//TODO
},
+ { "Channel settings are not unique!",
+ "Kanaleinstellungen sind nicht eindeutig!",
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ },
{ "Channel locked (recording)!",
"Kanal blockiert (zeichnet auf)!",
"Zaklenjen kanal (snemanje)!",
diff --git a/menu.c b/menu.c
index 47ad091..2e29b02 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.222 2002/11/01 12:15:45 kls Exp $
+ * $Id: menu.c 1.224 2002/11/10 16:05:15 kls Exp $
*/
#include "menu.h"
@@ -546,16 +546,18 @@ private:
cChannel data;
void Setup(void);
public:
- cMenuEditChannel(int Index);
+ cMenuEditChannel(cChannel *Channel, bool New = false);
virtual eOSState ProcessKey(eKeys Key);
};
-cMenuEditChannel::cMenuEditChannel(int Index)
+cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New)
:cOsdMenu(tr("Edit channel"), 14)
{
- channel = Channels.Get(Index);
+ channel = Channel;
if (channel) {
data = *channel;
+ if (New)
+ channel = NULL;
Setup();
}
}
@@ -603,10 +605,26 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
if (state == osUnknown) {
if (Key == kOk) {
- if (channel)
- *channel = data;
- Channels.Save();
- state = osBack;
+ if (Channels.HasUniqueChannelID(&data, channel)) {
+ if (channel) {
+ *channel = data;
+ isyslog("edited channel %d %s", channel->Number(), data.ToText());
+ state = osBack;
+ }
+ else {
+ channel = new cChannel;
+ *channel = data;
+ Channels.Add(channel);
+ Channels.ReNumber();
+ isyslog("added channel %d %s", channel->Number(), data.ToText());
+ state = osUser1;
+ }
+ Channels.Save();
+ }
+ else {
+ Interface->Error(tr("Channel settings are not unique!"));
+ state = osContinue;
+ }
}
}
if (Key != kNone && (data.source & cSource::st_Mask) != (oldSource & cSource::st_Mask))
@@ -651,7 +669,7 @@ protected:
eOSState Switch(void);
eOSState Edit(void);
eOSState New(void);
- eOSState Del(void);
+ eOSState Delete(void);
virtual void Move(int From, int To);
public:
cMenuChannels(void);
@@ -696,10 +714,8 @@ eOSState cMenuChannels::Edit(void)
if (HasSubMenu() || Count() == 0)
return osContinue;
cChannel *ch = Channels.Get(Current());
- if (ch) {
- isyslog("editing channel %d", ch->Number());
- return AddSubMenu(new cMenuEditChannel(Current()));
- }
+ if (ch)
+ return AddSubMenu(new cMenuEditChannel(ch));
return osContinue;
}
@@ -707,16 +723,10 @@ eOSState cMenuChannels::New(void)
{
if (HasSubMenu())
return osContinue;
- cChannel *channel = new cChannel(Channels.Get(Current()));
- Channels.Add(channel);
- Channels.ReNumber();
- Add(new cMenuChannelItem(channel), true);
- Channels.Save();
- isyslog("channel %d added", channel->Number());
- return AddSubMenu(new cMenuEditChannel(Current()));
+ return AddSubMenu(new cMenuEditChannel(Channels.Get(Current()), true));
}
-eOSState cMenuChannels::Del(void)
+eOSState cMenuChannels::Delete(void)
{
if (Count() > 0) {
int Index = Current();
@@ -753,16 +763,27 @@ eOSState cMenuChannels::ProcessKey(eKeys Key)
{
eOSState state = cOsdMenu::ProcessKey(Key);
- if (state == osUnknown) {
- switch (Key) {
- case kOk: return Switch();
- case kRed: return Edit();
- case kGreen: return New();
- case kYellow: return Del();
- case kBlue: Mark(); break;
- default: break;
- }
- }
+ switch (state) {
+ case osUser1: {
+ cChannel *channel = Channels.Last();
+ if (channel) {
+ Add(new cMenuChannelItem(channel), true);
+ return CloseSubMenu();
+ }
+ }
+ break;
+ default:
+ if (state == osUnknown) {
+ switch (Key) {
+ case kOk: return Switch();
+ case kRed: return Edit();
+ case kGreen: return New();
+ case kYellow: return Delete();
+ case kBlue: Mark(); break;
+ default: break;
+ }
+ }
+ }
return state;
}
@@ -924,7 +945,7 @@ class cMenuTimers : public cOsdMenu {
private:
eOSState Edit(void);
eOSState New(void);
- eOSState Del(void);
+ eOSState Delete(void);
eOSState OnOff(void);
virtual void Move(int From, int To);
eOSState Summary(void);
@@ -991,7 +1012,7 @@ eOSState cMenuTimers::New(void)
return AddSubMenu(new cMenuEditTimer(timer->Index(), true));
}
-eOSState cMenuTimers::Del(void)
+eOSState cMenuTimers::Delete(void)
{
// Check if this timer is active:
cTimer *ti = CurrentTimer();
@@ -1040,7 +1061,7 @@ eOSState cMenuTimers::ProcessKey(eKeys Key)
case kOk: return Summary();
case kRed: return Edit();
case kGreen: return New();
- case kYellow: return Del();
+ case kYellow: return Delete();
case kBlue: if (Setup.SortTimers)
OnOff();
else
@@ -1068,7 +1089,7 @@ cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch)
{
eventInfo = EventInfo;
if (eventInfo) {
- cChannel *channel = Channels.GetByServiceID(eventInfo->GetServiceID());
+ cChannel *channel = Channels.GetByChannelID(eventInfo->GetChannelID());
if (channel) {
char *buffer;
asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
@@ -1162,7 +1183,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha
pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
if (pArray[num]) {
- cChannel *channel = Channels.GetByServiceID(pArray[num]->GetServiceID());
+ cChannel *channel = Channels.GetByChannelID(pArray[num]->GetChannelID());
if (channel) {
pArray[num]->SetChannelNumber(channel->Number());
num++;
@@ -1192,7 +1213,7 @@ eOSState cMenuWhatsOn::Switch(void)
{
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
if (item) {
- cChannel *channel = Channels.GetByServiceID(item->eventInfo->GetServiceID());
+ cChannel *channel = Channels.GetByChannelID(item->eventInfo->GetChannelID());
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
return osEnd;
}
@@ -1313,7 +1334,7 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
SetTitle(buffer);
free(buffer);
if (schedules) {
- const cSchedule *Schedule = Channel->Sid() ? schedules->GetSchedule(Channel->Sid()) : schedules->GetSchedule();
+ const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
int num = Schedule->NumEvents();
const cEventInfo **pArray = MALLOC(const cEventInfo *, num);
if (pArray) {
@@ -1376,7 +1397,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
if (!now && !next) {
int ChannelNr = 0;
if (Count()) {
- cChannel *channel = Channels.GetByServiceID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetServiceID());
+ cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetChannelID());
if (channel)
ChannelNr = channel->Number();
}
@@ -1403,7 +1424,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
now = next = false;
const cEventInfo *ei = cMenuWhatsOn::ScheduleEventInfo();
if (ei) {
- cChannel *channel = Channels.GetByServiceID(ei->GetServiceID());
+ cChannel *channel = Channels.GetByChannelID(ei->GetChannelID());
if (channel) {
PrepareSchedule(channel);
if (channel->Number() != cDevice::CurrentChannel()) {
@@ -2713,7 +2734,7 @@ bool cRecordControl::GetEventInfo(void)
cMutexLock MutexLock;
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
if (Schedules) {
- const cSchedule *Schedule = Schedules->GetSchedule(channel->Sid());
+ const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
if (Schedule) {
eventInfo = Schedule->GetEventAround(Time);
if (eventInfo) {
diff --git a/osd.c b/osd.c
index acd9aec..8324874 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.36 2002/10/13 10:31:28 kls Exp $
+ * $Id: osd.c 1.37 2002/11/10 12:30:09 kls Exp $
*/
#include "osd.h"
@@ -599,20 +599,24 @@ eOSState cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
delete subMenu;
subMenu = SubMenu;
subMenu->Display();
- return osContinue; // convenience return value (see cMenuMain)
+ return osContinue; // convenience return value
+}
+
+eOSState cOsdMenu::CloseSubMenu()
+{
+ delete subMenu;
+ subMenu = NULL;
+ RefreshCurrent();
+ Display();
+ return osContinue; // convenience return value
}
eOSState cOsdMenu::ProcessKey(eKeys Key)
{
if (subMenu) {
eOSState state = subMenu->ProcessKey(Key);
- if (state == osBack) {
- delete subMenu;
- subMenu = NULL;
- RefreshCurrent();
- Display();
- state = osContinue;
- }
+ if (state == osBack)
+ return CloseSubMenu();
return state;
}
diff --git a/osd.h b/osd.h
index 861b04e..9fb515b 100644
--- a/osd.h
+++ b/osd.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.h 1.34 2002/08/11 11:42:15 kls Exp $
+ * $Id: osd.h 1.36 2002/11/10 12:28:57 kls Exp $
*/
#ifndef __OSD_H
@@ -107,7 +107,7 @@ public:
virtual void Display(int Offset = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
virtual void Set(void) {}
virtual eOSState ProcessKey(eKeys Key);
-};
+ };
class cOsdObject {
protected:
@@ -119,7 +119,7 @@ public:
int Height(void) { return Interface->Height(); }
bool NeedsFastResponse(void) { return needsFastResponse; }
virtual eOSState ProcessKey(eKeys Key) { return osUnknown; }
-};
+ };
class cOsdMenu : public cOsdObject, public cList<cOsdItem> {
private:
@@ -147,6 +147,7 @@ protected:
void Mark(void);
eOSState HotKey(eKeys Key);
eOSState AddSubMenu(cOsdMenu *SubMenu);
+ eOSState CloseSubMenu();
bool HasSubMenu(void) { return subMenu; }
void SetStatus(const char *s);
void SetTitle(const char *Title, bool ShowDate = true);
diff --git a/remote.h b/remote.h
index 35cf62e..b23b933 100644
--- a/remote.h
+++ b/remote.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remote.h 1.19 2002/11/01 10:48:11 kls Exp $
+ * $Id: remote.h 1.20 2002/11/09 11:07:33 kls Exp $
*/
#ifndef __REMOTE_H
@@ -16,8 +16,6 @@
#include "thread.h"
#include "tools.h"
-typedef unsigned long long int uint64;
-
class cRemote : public cListObject {
private:
enum { MaxKeys = MAXKEYSINMACRO };
diff --git a/svdrp.c b/svdrp.c
index 2859fb9..66b420c 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 1.48 2002/10/20 12:45:03 kls Exp $
+ * $Id: svdrp.c 1.49 2002/11/10 12:09:56 kls Exp $
*/
#include "svdrp.h"
@@ -776,15 +776,20 @@ void cSVDRP::CmdMODC(const char *Option)
tail = skipspace(tail);
cChannel *channel = Channels.GetByNumber(n);
if (channel) {
- cChannel c = *channel;
- if (!c.Parse(tail)) {
- Reply(501, "Error in channel settings");
- return;
+ cChannel ch;
+ if (ch.Parse(tail, true)) {
+ if (Channels.HasUniqueChannelID(&ch, channel)) {
+ *channel = ch;
+ Channels.ReNumber();
+ Channels.Save();
+ isyslog("modifed channel %d %s", channel->Number(), channel->ToText());
+ Reply(250, "%d %s", channel->Number(), channel->ToText());
+ }
+ else
+ Reply(501, "Channel settings are not unique");
}
- *channel = c;
- Channels.Save();
- isyslog("channel %d modified", channel->Number());
- Reply(250, "%d %s", channel->Number(), channel->ToText());
+ else
+ Reply(501, "Error in channel settings");
}
else
Reply(501, "Channel \"%d\" not defined", n);
@@ -844,13 +849,19 @@ void cSVDRP::CmdMOVT(const char *Option)
void cSVDRP::CmdNEWC(const char *Option)
{
if (*Option) {
- cChannel *channel = new cChannel;
- if (channel->Parse(Option)) {
- Channels.Add(channel);
- Channels.ReNumber();
- Channels.Save();
- isyslog("channel %d added", channel->Number());
- Reply(250, "%d %s", channel->Number(), channel->ToText());
+ cChannel ch;
+ if (ch.Parse(Option, true)) {
+ if (Channels.HasUniqueChannelID(&ch)) {
+ cChannel *channel = new cChannel;
+ *channel = ch;
+ Channels.Add(channel);
+ Channels.ReNumber();
+ Channels.Save();
+ isyslog("new channel %d %s", channel->Number(), channel->ToText());
+ Reply(250, "%d %s", channel->Number(), channel->ToText());
+ }
+ else
+ Reply(501, "Channel settings are not unique");
}
else
Reply(501, "Error in channel settings");
diff --git a/timers.c b/timers.c
index 76f86a5..6044522 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.c 1.1 2002/10/20 12:28:55 kls Exp $
+ * $Id: timers.c 1.2 2002/11/10 10:19:12 kls Exp $
*/
#include "timers.h"
@@ -49,7 +49,7 @@ cTimer::cTimer(const cEventInfo *EventInfo)
startTime = stopTime = 0;
recording = pending = false;
active = true;
- channel = Channels.GetByServiceID(EventInfo->GetServiceID());
+ channel = Channels.GetByChannelID(EventInfo->GetChannelID());
time_t tstart = EventInfo->GetTime();
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
tstart -= Setup.MarginStart * 60;
@@ -92,22 +92,17 @@ bool cTimer::operator< (const cListObject &ListObject)
return t1 < t2 || (t1 == t2 && priority > ti->priority);
}
-const char *cTimer::ToText(cTimer *Timer)
+const char *cTimer::ToText(bool UseChannelID)
{
free(buffer);
- strreplace(Timer->file, ':', '|');
- strreplace(Timer->summary, '\n', '|');
- asprintf(&buffer, "%d:%d:%s:%04d:%04d:%d:%d:%s:%s\n", Timer->active, Timer->Channel()->Number(), PrintDay(Timer->day, Timer->firstday), Timer->start, Timer->stop, Timer->priority, Timer->lifetime, Timer->file, Timer->summary ? Timer->summary : "");
- strreplace(Timer->summary, '|', '\n');
- strreplace(Timer->file, '|', ':');
+ strreplace(file, ':', '|');
+ strreplace(summary, '\n', '|');
+ asprintf(&buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s\n", active, UseChannelID ? Channel()->GetChannelIDStr() : itoa(Channel()->Number()), PrintDay(day, firstday), start, stop, priority, lifetime, file, summary ? summary : "");
+ strreplace(summary, '|', '\n');
+ strreplace(file, '|', ':');
return buffer;
}
-const char *cTimer::ToText(void)
-{
- return ToText(this);
-}
-
int cTimer::TimeToInt(int t)
{
return (t / 100 * 60 + t % 100) * 60;
@@ -189,8 +184,9 @@ const char *cTimer::PrintFirstDay(void)
bool cTimer::Parse(const char *s)
{
- char *buffer1 = NULL;
- char *buffer2 = NULL;
+ char *channelbuffer = NULL;
+ char *daybuffer = NULL;
+ char *filebuffer = NULL;
free(summary);
summary = NULL;
//XXX Apparently sscanf() doesn't work correctly if the last %a argument
@@ -208,34 +204,35 @@ bool cTimer::Parse(const char *s)
strcat(strn0cpy(s2, s, l2 + 1), " \n");
s = s2;
}
- int ch = 0;
- if (8 <= sscanf(s, "%d :%d :%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &active, &ch, &buffer1, &start, &stop, &priority, &lifetime, &buffer2, &summary)) {
+ bool result = false;
+ if (8 <= sscanf(s, "%d :%a[^:]:%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &active, &channelbuffer, &daybuffer, &start, &stop, &priority, &lifetime, &filebuffer, &summary)) {
if (summary && !*skipspace(summary)) {
free(summary);
summary = NULL;
}
//TODO add more plausibility checks
- day = ParseDay(buffer1, &firstday);
- strn0cpy(file, buffer2, MaxFileName);
+ day = ParseDay(daybuffer, &firstday);
+ result = day != 0;
+ strn0cpy(file, filebuffer, MaxFileName);
strreplace(file, '|', ':');
strreplace(summary, '|', '\n');
- free(buffer1);
- free(buffer2);
- free(s2);
- channel = Channels.GetByNumber(ch);
+ uint64 cid = cChannel::StringToChannelID(channelbuffer);
+ channel = cid ? Channels.GetByChannelID(cid) : Channels.GetByNumber(atoi(channelbuffer));
if (!channel) {
- esyslog("ERROR: channel %d not defined", ch);
- return false;
+ esyslog("ERROR: channel %s not defined", channelbuffer);
+ result = false;
}
- return day != 0;
}
+ free(channelbuffer);
+ free(daybuffer);
+ free(filebuffer);
free(s2);
- return false;
+ return result;
}
bool cTimer::Save(FILE *f)
{
- return fprintf(f, ToText()) > 0;
+ return fprintf(f, ToText(true)) > 0;
}
bool cTimer::IsSingleEvent(void)
diff --git a/timers.h b/timers.h
index 8dc762e..933c88e 100644
--- a/timers.h
+++ b/timers.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.h 1.1 2002/10/20 11:52:23 kls Exp $
+ * $Id: timers.h 1.2 2002/11/10 10:17:05 kls Exp $
*/
#ifndef __TIMERS_H
@@ -36,7 +36,6 @@ private:
char file[MaxFileName];
time_t firstday;
char *summary;
- static const char *ToText(cTimer *Timer);
public:
cTimer(bool Instant = false);
cTimer(const cEventInfo *EventInfo);
@@ -55,7 +54,7 @@ public:
const char *File(void) { return file; }
time_t FirstDay(void) { return firstday; }
const char *Summary(void) { return summary; }
- const char *ToText(void);
+ const char *ToText(bool UseChannelID = false);
bool Parse(const char *s);
bool Save(FILE *f);
bool IsSingleEvent(void);
diff --git a/tools.c b/tools.c
index df2d570..68bfb7e 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.c 1.72 2002/10/19 12:32:53 kls Exp $
+ * $Id: tools.c 1.73 2002/11/09 15:33:47 kls Exp $
*/
#include "tools.h"
@@ -243,6 +243,13 @@ bool isnumber(const char *s)
return true;
}
+const char *itoa(int n)
+{
+ static char buf[16];
+ snprintf(buf, sizeof(buf), "%d", n);
+ return buf;
+}
+
const char *AddDirectory(const char *DirName, const char *FileName)
{
static char *buf = NULL;
diff --git a/tools.h b/tools.h
index 08f2429..efa2de6 100644
--- a/tools.h
+++ b/tools.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: tools.h 1.51 2002/10/19 12:31:50 kls Exp $
+ * $Id: tools.h 1.52 2002/11/09 15:32:36 kls Exp $
*/
#ifndef __TOOLS_H
@@ -20,6 +20,7 @@
#include <sys/types.h>
typedef unsigned char uchar;
+typedef unsigned long long int uint64;
extern int SysLogLevel;
@@ -68,6 +69,7 @@ int numdigits(int n);
int time_ms(void);
void delay_ms(int ms);
bool isnumber(const char *s);
+const char *itoa(int n); // returns a statically allocated string!
const char *AddDirectory(const char *DirName, const char *FileName); // returns a statically allocated string!
int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
bool DirectoryOk(const char *DirName, bool LogErrors = false);
diff --git a/vdr.5 b/vdr.5
index 2db8a7b..9720a65 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,9 +8,9 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 1.11 2002/10/27 15:36:44 kls Exp $
+.\" $Id: vdr.5 1.12 2002/11/10 10:10:15 kls Exp $
.\"
-.TH vdr 5 "7 Oct 2002" "1.2.0" "Video Disk Recorder Files"
+.TH vdr 5 "10 Nov 2002" "1.2.0" "Video Disk Recorder Files"
.SH NAME
vdr file formats - the Video Disk Recorder Files
.SH DESCRIPTION
@@ -120,6 +120,18 @@ l l.
.TP
.B SID
The service ID of this channel.
+.PP
+A particular channel can be uniquely identified by its \fBchannel\ ID\fR,
+which is a string that looks like this:
+
+\fBS19.2E-0-12188-12003\fR
+
+The components of this string are the \fBSource\fR (S19.2E), \fBFrequency\fR
+(12188, MHz) and \fBSID\fR (12003) as defined above. The part that is currently
+\fB0\fR is reserved for future use.
+.br
+The \fBchannel\ ID\fR is used in the \fItimers.conf\fR and \fIepg.data\fR
+files to properly identify the channels.
.SS TIMERS
The file \fItimers.conf\fR contains the timer setup.
Each line contains one timer definition, with individual fields
@@ -143,7 +155,13 @@ Note: in order to allow future extensibility, external programs using the
and leave the lower 16 bit untouched.
.TP
.B Channel
-The number of the channel to record.
+The channel to record from. This is either the channel number as shown in the
+on-screen menus, or a complete channel ID. When reading \fItimers.conf\fR
+any channel numbers will be mapped to the respective channel ids and when
+the file is written again, there will only be channel ids. Channel numbers
+are accepted as input in order to allow easier creation of timers when
+manually editing \fItimers.conf\fR. Also, when timers are listed via SVDRP
+commands, the channels are given as numbers.
.TP
.B Day
The day when this timer shall record.
@@ -472,7 +490,7 @@ The following tag characters are defined:
.TS
tab (@);
l l.
-\fBC\fR@<service id> <channel name>
+\fBC\fR@<channel id> <channel name>
\fBE\fR@<event id> <start time> <duration> <table id>
\fBT\fR@<title>
\fBS\fR@<subtitle>
@@ -491,8 +509,8 @@ should at least have a \fBT\fR entry).
.TS
tab (@);
l l.
-<service id> @is the "program number" as defined in 'channels.conf'
-<channel name> @is the "name" as in 'channels.conf' (for information only)
+<channel id> @is the "channel ID", made up from the parameters defined in 'channels.conf'
+<channel name> @is the "name" as in 'channels.conf' (for information only, may be left out)
<start time> @is the time (as a time_t integer) in UTC when this event starts
<duration> @is the time (in seconds) that this event will take
<table id> @is a hex number that indicates the table this event is contained\