summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS23
-rw-r--r--HISTORY46
-rw-r--r--Makefile11
-rw-r--r--PLUGINS.html31
-rw-r--r--channels.c445
-rw-r--r--channels.conf356
-rw-r--r--channels.conf.cable371
-rw-r--r--channels.conf.terr27
-rw-r--r--channels.h124
-rw-r--r--config.c202
-rw-r--r--config.h52
-rw-r--r--device.c58
-rw-r--r--device.h4
-rw-r--r--diseqc.c136
-rw-r--r--diseqc.conf30
-rw-r--r--diseqc.h60
-rw-r--r--dvbdevice.c282
-rw-r--r--dvbdevice.h6
-rw-r--r--eit.c10
-rw-r--r--eitscan.c9
-rw-r--r--i18n.c254
-rw-r--r--interface.c3
-rw-r--r--menu.c277
-rw-r--r--menu.h4
-rw-r--r--params.txt4
-rw-r--r--recording.c3
-rw-r--r--sources.c104
-rw-r--r--sources.conf50
-rw-r--r--sources.h45
-rw-r--r--svdrp.c27
-rw-r--r--vdr.5115
-rw-r--r--vdr.c9
32 files changed, 2303 insertions, 875 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 260cb59..6b8de52 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -152,6 +152,7 @@ Stefan Huelswitt <huels@iname.com>
for making cStatus::MsgChannelSwitch() only be called if a channel is actually going to
be switched or has actually been switched successfully
for adding a missing StripAudioPackets() to cDvbPlayer::Action()
+ for improving skipping channels that are (currently) not available
Ulrich Röder <roeder@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than
@@ -176,6 +177,8 @@ Andreas Schultz <aschultz@warp10.net>
for implementing an SPU decoder
for fixing opening /dev/video in cDvbDevice::GrabImage() in case of NEWSTRUCT driver
for reporting a problem with plugin Makefiles and the NEWSTRUCT driver
+ for pointing out some unnecessary #includes in eit.c and a problem with
+ cMenuRecordings::Del(), which caused warnings with gcc-3.2
Aaron Holtzman
for writing 'ac3dec'
@@ -184,7 +187,8 @@ Wolfgang Henselmann-Weiss <Wolfgang_Henselmann@betaresearch.de>
for fixing calculating the timeout value in cFile::FileReady()
Uwe Scheffler <UweScheffler@t-online.de>
- for his help in keeping 'channels.conf.cable' up to date
+ for his help in keeping 'channels.conf.cable' and 'channels.conf.terr' up to date
+ for helping to test new DVB-T handling
Matjaz Thaler <matjaz.thaler@guest.arnes.si>
for improving AC3 decoding when replaying DVDs
@@ -400,7 +404,22 @@ Jürgen Zimmermann <jnzimmer@informatik.uni-kl.de>
for adding some missing #includes to files in libdtv for gcc 3.2
Helmut Auer <vdr@helmutauer.de>
- for reporting a superfluous error message in cLockFile.
+ for reporting a superfluous error message in cLockFile
Jeremy Hall <jhall@UU.NET>
for fixing an incomplete initialization of the filter parameters in eit.c
+
+Oliver Endriss <o.endriss@gmx.de>
+ for fixing a missing Flush() call in the remote control learning procedure
+ for helping to test and debug the new channel source and DiSEqC handling
+ for reporting a bug when pressing the "Blue" button in the main menu without
+ having displayed it
+
+Reinhard Walter Buchner <rw.buchner@freenet.de>
+ for adding some satellites to 'sources.conf'
+
+Lauri Tischler <lauri.tischler@efore.fi>
+ for helping to test and debug the new channel source and DiSEqC handling
+
+Andy Carter <fruit@ukgateway.net>
+ for helping to test new DVB-T handling
diff --git a/HISTORY b/HISTORY
index 12146a0..b9140fe 100644
--- a/HISTORY
+++ b/HISTORY
@@ -93,7 +93,7 @@ Video Disk Recorder Revision History
- The program can now run in full background mode by using the --daemon option.
- Added a "summary" field to the timers (thanks to Carsten Koch!).
This field can contain a descriptive text of the programme and will be
- displayed when the "Blue" key is pressed on a recording that was created by
+ displayed when the "Blue" button is pressed on a recording that was created by
this timer. If the text contains the special character '|', a newline will
be inserted at that place. When pressing "Ok" on a timer that contains a
summary field, the summary will be displayed. To edit such a timer the "Red"
@@ -1535,3 +1535,47 @@ Video Disk Recorder Revision History
- Fixed handling DVD subtitles in the SPU decoder (thanks to Andreas Schultz).
- Avoiding restarts due to 'panic level' when switching channels on the primary
device during EPG scan.
+
+2002-10-06: Version 1.1.12
+
+- Fixed a missing Flush() call in the remote control learning procedure (thanks
+ to Oliver Endriss).
+- Modified channel handling to cover all parameters necessary for DVB-C and DVB-T
+ (see man vdr(5) for the meaning of the additional parameters stored in the field
+ previously named 'polarisation'). Thanks to Uwe Scheffler and Andy Carter for testing.
+ If you have a system with different kinds of DVB cards, like DVB-T and DVB-C,
+ for instance, there is no more need to distinguish the channels through the
+ 'Ca' parameter in order to assign them to the various DVB cards. This is now
+ taken care of by the "source" parameter. So a channel marked as "terrestrial",
+ for example, will only be received on DVB-T cards.
+ Note that the cChannel class has been moved into a separate file (channels.[ch]),
+ and that all data members have been made private and are now only accessible
+ through member functions. You may have to change any plugin code that accesses
+ cChannel data accordingly.
+- The new configuration file 'sources.conf' contains the various signal sources
+ (satellites, cable and terrestrial) which are used in 'channels.conf' and
+ 'diseqc.conf' (thanks to Reinhard Walter Buchner for adding some satellites to
+ 'sources.conf' and Oliver Endriss and Lauri Tischler for testing and debugging).
+- The 'diseqc' parameter in the channel definitions has been redefined to hold the
+ "source" of the given channel (which can be either a satellite, cable or terrestrial).
+ For compatibility with channels.conf files from older versions, numeric values in
+ this parameter will be tolerated, but they have no meaning. If you want to use
+ DiSEqC you will need to replace these old values with the proper source identifiers
+ defined in the new configuration file 'sources.conf'. See how this is done in the
+ 'channels.conf' file that comes with the VDR package.
+- The new configuration file 'diseqc.conf' can be used to set up the individual
+ diseqc configuration (see man vdr(5) for a description of the file format).
+- The "Edit channel" menu has a new entry "Source:" in which the source of this
+ channel can be selected (either a satellite, cable or terrestrial). The set of
+ parameters at the end of this menu will change according to the type of source.
+- The "Use DiSEqC" parameter in the "Setup/LNB" menu has been moved to the beginning
+ of the list and disables the rest of the parameters when set to "yes", since these
+ are now only meaningful if DiSEqC is _not_ used.
+- Removed some unnecessary #includes from eit.c and changed cMenuRecordings::Del()
+ to cMenuRecordings::Delete() to avoid warnings in gcc-3.2 (thanks to Andreas
+ Schultz for pointing this out).
+- Improved skipping channels that are (currently) not available (thanks to Stefan
+ Huelswitt).
+- Updated channels.conf.terr and channels.conf.cable (thanks to Uwe Scheffler).
+- Fixed a bug when pressing the "Blue" button in the main menu without having
+ displayed it (thanks to Oliver Endriss for reporting this one).
diff --git a/Makefile b/Makefile
index 3902b39..cfb6f3a 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 1.47 2002/09/28 14:12:43 kls Exp $
+# $Id: Makefile 1.48 2002/10/04 14:29:14 kls Exp $
.DELETE_ON_ERROR:
@@ -32,10 +32,11 @@ endif
DTVLIB = $(DTVDIR)/libdtv.a
-OBJS = audio.o config.o cutter.o device.o dvbdevice.o dvbosd.o dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o\
- interface.o keys.o lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o receiver.o\
- recorder.o recording.o remote.o remux.o ringbuffer.o spu.o status.o svdrp.o thread.o\
- tools.o transfer.o vdr.o videodir.o
+OBJS = audio.o channels.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd.o\
+ dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\
+ lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\
+ receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sources.o\
+ spu.o status.o svdrp.o thread.o tools.o transfer.o vdr.o videodir.o
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
diff --git a/PLUGINS.html b/PLUGINS.html
index 55e935b..4c4592d 100644
--- a/PLUGINS.html
+++ b/PLUGINS.html
@@ -21,18 +21,18 @@ VDR program and present itself to the user.
The <i>inside</i> interface provides the plugin code access to VDR's internal data
structures and allows it to hook itself into specific areas to perform special actions.
<p>
-<!--X1.1.7--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.1.7 are marked like this.
-<!--X1.1.7--></td></tr></table>
-<!--X1.1.8--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.8 are marked like this.
<!--X1.1.8--></td></tr></table>
-<!--X1.1.9--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.9 are marked like this.
<!--X1.1.9--></td></tr></table>
-<!--X1.1.11--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.11 are marked like this.
<!--X1.1.11--></td></tr></table>
+<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+Important modifications introduced in version 1.1.12 are marked like this.
+<!--X1.1.12--></td></tr></table>
<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
@@ -957,7 +957,6 @@ stream. There are no prerequisites regarding the length or alignment of an
individual block of data. The sum of all blocks must simply result in the
desired video data stream, and it must be delivered fast enough so that the
DVB device doesn't run out of data.
-<!--X1.1.7--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
To avoid busy loops the player should call its member function
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
@@ -965,7 +964,6 @@ bool DevicePoll(cPoller &amp;Poller, int TimeoutMs = 0);
</pre></td></tr></table><p>
to determine whether the device is ready for further data.
-<!--X1.1.7--></td></tr></table>
<p>
TODO: PlayAudio()???
<p>
@@ -1184,14 +1182,17 @@ the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards.
If the new device can receive, it most likely needs to provide a way of
selecting which channel it shall tune to:
-<!--X1.1.9--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+virtual bool ProvidesSource(int Source) const;
+<!--X1.1.12--></td></tr></table>
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL);
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
</pre></td></tr></table><p>
-These functions will be called with the desired channel and shall return whether
-this device can provide the requested channel and whether tuning to it was successful,
+These functions will be called with the desired source or channel and shall return whether
+this device can provide the requested source or channel and whether tuning to it was successful,
repectively.
<!--X1.1.9--></td></tr></table>
<p>
@@ -1203,7 +1204,7 @@ A device that can be used for recording must implement the functions
virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
virtual bool OpenDvr(void);
virtual void CloseDvr(void);
-<!--X1.1.9--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
virtual bool GetTSPacket(uchar *&amp;Data);
<!--X1.1.9--></td></tr></table>
</pre></td></tr></table><p>
@@ -1227,7 +1228,6 @@ to indicate this to VDR.
<p>
The functions to implement replaying capabilites are
-<!--X1.1.7--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
virtual bool HasDecoder(void) const;
virtual bool SetPlayMode(ePlayMode PlayMode);
@@ -1240,7 +1240,6 @@ virtual void StillPicture(const uchar *Data, int Length);
virtual bool Poll(cPoller &amp;Poller, int TimeoutMs = 0);
virtual int PlayVideo(const uchar *Data, int Length);
</pre></td></tr></table><p>
-<!--X1.1.7--></td></tr></table>
In addition, the following functions may be implemented to provide further
functionality:
@@ -1251,7 +1250,7 @@ virtual void SetVideoFormat(bool VideoFormat16_9);
virtual void SetVolumeDevice(int Volume);
</pre></td></tr></table><p>
-<!--X1.1.8--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<p>
<b>On Screen Display</b>
<p>
@@ -1292,7 +1291,7 @@ shut down (delete) all devices when the program terminates. It is therefore
important that the devices are created on the heap, using the <tt>new</tt>
operator!
-<!--X1.1.11--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<hr><h2>Remote Control</h2>
<center><i><b>The joy of zapping!</b></i></center><p>
diff --git a/channels.c b/channels.c
new file mode 100644
index 0000000..f86f8ef
--- /dev/null
+++ b/channels.c
@@ -0,0 +1,445 @@
+/*
+ * channels.c: Channel handling
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: channels.c 1.3 2002/10/06 12:41:49 kls Exp $
+ */
+
+#include "channels.h"
+#ifdef NEWSTRUCT
+#include <linux/dvb/frontend.h>
+#else
+#include <ost/frontend.h>
+#endif
+#include <ctype.h>
+
+// IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
+// format characters in order to allow any number of blanks after a numeric
+// value!
+
+// -- Channel Parameter Maps -------------------------------------------------
+
+const tChannelParameterMap InversionValues[] = {
+ { 0, INVERSION_OFF },
+ { 1, INVERSION_ON },
+ { 999, INVERSION_AUTO },
+ { -1 }
+ };
+
+const tChannelParameterMap BandwidthValues[] = {
+ { 6, BANDWIDTH_6_MHZ },
+ { 7, BANDWIDTH_7_MHZ },
+ { 8, BANDWIDTH_8_MHZ },
+#ifdef NEWSTRUCT
+ { 999, BANDWIDTH_AUTO },
+#endif
+ { -1 }
+ };
+
+const tChannelParameterMap CoderateValues[] = {
+ { 0, FEC_NONE },
+ { 12, FEC_1_2 },
+ { 23, FEC_2_3 },
+ { 34, FEC_3_4 },
+#ifdef NEWSTRUCT
+ { 45, FEC_4_5 },
+#endif
+ { 56, FEC_5_6 },
+#ifdef NEWSTRUCT
+ { 67, FEC_6_7 },
+#endif
+ { 78, FEC_7_8 },
+#ifdef NEWSTRUCT
+ { 89, FEC_8_9 },
+#endif
+ { 999, FEC_AUTO },
+ { -1 }
+ };
+
+const tChannelParameterMap ModulationValues[] = {
+ { 0, QPSK },
+ { 16, QAM_16 },
+ { 32, QAM_32 },
+ { 64, QAM_64 },
+ { 128, QAM_128 },
+ { 256, QAM_256 },
+#ifdef NEWSTRUCT
+ { 999, QAM_AUTO },
+#endif
+ { -1 }
+ };
+
+const tChannelParameterMap TransmissionValues[] = {
+ { 2, TRANSMISSION_MODE_2K },
+ { 8, TRANSMISSION_MODE_8K },
+#ifdef NEWSTRUCT
+ { 999, TRANSMISSION_MODE_AUTO },
+#endif
+ { -1 }
+ };
+
+const tChannelParameterMap GuardValues[] = {
+ { 4, GUARD_INTERVAL_1_4 },
+ { 8, GUARD_INTERVAL_1_8 },
+ { 16, GUARD_INTERVAL_1_16 },
+ { 32, GUARD_INTERVAL_1_32 },
+#ifdef NEWSTRUCT
+ { 999, GUARD_INTERVAL_AUTO },
+#endif
+ { -1 }
+ };
+
+const tChannelParameterMap HierarchyValues[] = {
+ { 0, HIERARCHY_NONE },
+ { 1, HIERARCHY_1 },
+ { 2, HIERARCHY_2 },
+ { 4, HIERARCHY_4 },
+#ifdef NEWSTRUCT
+ { 999, HIERARCHY_AUTO },
+#endif
+ { -1 }
+ };
+
+int UserIndex(int Value, const tChannelParameterMap *Map)
+{
+ const tChannelParameterMap *map = Map;
+ while (map && map->userValue != -1) {
+ if (map->userValue == Value)
+ return map - Map;
+ map++;
+ }
+ return -1;
+}
+
+int DriverIndex(int Value, const tChannelParameterMap *Map)
+{
+ const tChannelParameterMap *map = Map;
+ while (map && map->userValue != -1) {
+ if (map->driverValue == Value)
+ return map - Map;
+ map++;
+ }
+ return -1;
+}
+
+int MapToUser(int Value, const tChannelParameterMap *Map)
+{
+ int n = DriverIndex(Value, Map);
+ if (n >= 0)
+ return Map[n].userValue;
+ return -1;
+}
+
+int MapToDriver(int Value, const tChannelParameterMap *Map)
+{
+ int n = UserIndex(Value, Map);
+ if (n >= 0)
+ return Map[n].driverValue;
+ return -1;
+}
+
+// -- cChannel ---------------------------------------------------------------
+
+char *cChannel::buffer = NULL;
+
+cChannel::cChannel(void)
+{
+ *name = 0;
+ frequency = 0;
+ source = 0;
+ srate = 0;
+ vpid = 0;
+ apid1 = 0;
+ apid2 = 0;
+ dpid1 = 0;
+ dpid2 = 0;
+ tpid = 0;
+ ca = 0;
+ sid = 0;
+ groupSep = false;
+ //XXX
+ polarization = 'v';
+ inversion = INVERSION_AUTO;
+ bandwidth = BANDWIDTH_8_MHZ;
+ coderateH = FEC_AUTO;//XXX FEC_2_3
+ coderateL = FEC_1_2;//XXX
+ modulation = QAM_64;
+ transmission = TRANSMISSION_MODE_2K;
+ guard = GUARD_INTERVAL_1_32;
+ hierarchy = HIERARCHY_NONE;
+}
+
+cChannel::cChannel(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;
+ //XXX
+ polarization = Channel ? Channel->polarization : 'v';
+ inversion = Channel ? Channel->inversion : INVERSION_AUTO;
+ bandwidth = Channel ? Channel->bandwidth : BANDWIDTH_8_MHZ;
+ coderateH = Channel ? Channel->coderateH : FEC_AUTO;//XXX FEC_2_3
+ coderateL = Channel ? Channel->coderateL : FEC_1_2;//XXX
+ modulation = Channel ? Channel->modulation : QAM_64;
+ transmission = Channel ? Channel->transmission : TRANSMISSION_MODE_2K;
+ guard = Channel ? Channel->guard : GUARD_INTERVAL_1_32;
+ hierarchy = Channel ? Channel->hierarchy : HIERARCHY_NONE;
+}
+
+static int PrintParameter(char *p, char Name, int Value)
+{
+ //XXX return Value >= 0 && Value != 999 ? sprintf(p, "%c%d", Name, Value) : 0;
+ //XXX let's store 999 for the moment, until we generally switch to the NEWSTRUCT
+ //XXX driver (where the defaults will all be AUTO)
+ return Value >= 0 && (Value != 999 || (Name != 'I' && Name != 'C')) ? sprintf(p, "%c%d", Name, Value) : 0;
+}
+
+const char *cChannel::ParametersToString(void)
+{
+ char type = *cSource::ToString(source);
+#define ST(s) if (strchr(s, type))
+ static char buffer[64];
+ char *q = buffer;
+ *q = 0;
+ ST(" S ") q += sprintf(q, "%c", polarization);
+ ST("CST") q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues));
+ ST("CST") q += PrintParameter(q, 'C', MapToUser(coderateH, CoderateValues));
+ ST(" T") q += PrintParameter(q, 'D', MapToUser(coderateL, CoderateValues));
+ ST("C T") q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
+ ST(" T") q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues));
+ ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
+ ST(" T") q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
+ ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues));
+ return buffer;
+}
+
+static const char *ParseParameter(const char *s, int &Value, const tChannelParameterMap *Map)
+{
+ if (*++s) {
+ char *p = NULL;
+ errno = 0;
+ int n = strtol(s, &p, 10);
+ if (!errno && p != s) {
+ //XXX let's tolerate 999 for the moment, until we generally switch to the NEWSTRUCT
+ //XXX driver (where the defaults will all be AUTO)
+ //XXX Value = MapToDriver(n, Map);
+ //XXX if (Value >= 0)
+ //XXX return p;
+ int v = MapToDriver(n, Map);
+ if (v >= 0) {
+ Value = v;
+ return p;
+ }
+ else if (v == 999)
+ return p;
+ }
+ }
+ esyslog("ERROR: illegal value for parameter '%c'", *(s - 1));
+ return NULL;
+}
+
+bool cChannel::StringToParameters(const char *s)
+{
+ while (s && *s) {
+ switch (toupper(*s)) {
+ case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break;
+ case 'C': s = ParseParameter(s, coderateH, CoderateValues); break;
+ case 'D': s = ParseParameter(s, coderateL, CoderateValues); break;
+ case 'G': s = ParseParameter(s, guard, GuardValues); break;
+ case 'H': polarization = *s++; break;
+ case 'I': s = ParseParameter(s, inversion, InversionValues); break;
+ // 'L' reserved for possible circular polarization
+ case 'M': s = ParseParameter(s, modulation, ModulationValues); break;
+ // 'R' reserved for possible circular polarization
+ case 'T': s = ParseParameter(s, transmission, TransmissionValues); break;
+ case 'V': polarization = *s++; break;
+ case 'Y': s = ParseParameter(s, hierarchy, HierarchyValues); break;
+ default: esyslog("ERROR: unknown parameter key '%c'", *s);
+ return false;
+ }
+ }
+ return true;
+}
+
+const char *cChannel::ToText(cChannel *Channel)
+{
+ char buf[MaxChannelName * 2];
+ char *s = Channel->name;
+ if (strchr(s, ':')) {
+ s = strcpy(buf, s);
+ strreplace(s, ':', '|');
+ }
+ free(buffer);
+ if (Channel->groupSep)
+ asprintf(&buffer, ":%s\n", s);
+ else {
+ char apidbuf[32];
+ char *q = apidbuf;
+ q += snprintf(q, sizeof(apidbuf), "%d", Channel->apid1);
+ if (Channel->apid2)
+ q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->apid2);
+ if (Channel->dpid1 || Channel->dpid2)
+ q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ";%d", Channel->dpid1);
+ if (Channel->dpid2)
+ q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->dpid2);
+ *q = 0;
+ asprintf(&buffer, "%s:%d:%s:%s:%d:%d:%s:%d:%d:%d\n", s, Channel->frequency, Channel->ParametersToString(), cSource::ToString(Channel->source), Channel->srate, Channel->vpid, apidbuf, Channel->tpid, Channel->ca, Channel->sid);
+ }
+ return buffer;
+}
+
+const char *cChannel::ToText(void)
+{
+ return ToText(this);
+}
+
+bool cChannel::Parse(const char *s)
+{
+ if (*s == ':') {
+ if (*++s) {
+ strn0cpy(name, s, MaxChannelName);
+ groupSep = true;
+ number = 0;
+ }
+ else
+ return false;
+ }
+ else {
+ groupSep = false;
+ char *namebuf = NULL;
+ char *sourcebuf = NULL;
+ char *parambuf = NULL;
+ char *apidbuf = NULL;
+ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%d :%a[^:]:%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpid, &apidbuf, &tpid, &ca, &sid);
+ if (fields >= 9) {
+ if (fields == 9) {
+ // allow reading of old format
+ sid = ca;
+ ca = tpid;
+ tpid = 0;
+ }
+ apid1 = apid2 = 0;
+ dpid1 = dpid2 = 0;
+ bool ok = false;
+ if (parambuf && sourcebuf && apidbuf) {
+ ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0;
+ char *p = strchr(apidbuf, ';');
+ if (p)
+ *p++ = 0;
+ sscanf(apidbuf, "%d ,%d ", &apid1, &apid2);
+ if (p)
+ sscanf(p, "%d ,%d ", &dpid1, &dpid2);
+ }
+ strn0cpy(name, namebuf, MaxChannelName);
+ free(parambuf);
+ free(sourcebuf);
+ free(apidbuf);
+ free(namebuf);
+ return ok;
+ }
+ else
+ return false;
+ }
+ strreplace(name, '|', ':');
+ return true;
+}
+
+bool cChannel::Save(FILE *f)
+{
+ return fprintf(f, ToText()) > 0;
+}
+
+// -- cChannels --------------------------------------------------------------
+
+cChannels Channels;
+
+bool cChannels::Load(const char *FileName, bool AllowComments)
+{
+ if (cConfig<cChannel>::Load(FileName, AllowComments)) {
+ ReNumber();
+ return true;
+ }
+ return false;
+}
+
+int cChannels::GetNextGroup(int Idx)
+{
+ cChannel *channel = Get(++Idx);
+ while (channel && !channel->GroupSep())
+ channel = Get(++Idx);
+ return channel ? Idx : -1;
+}
+
+int cChannels::GetPrevGroup(int Idx)
+{
+ cChannel *channel = Get(--Idx);
+ while (channel && !channel->GroupSep())
+ channel = Get(--Idx);
+ return channel ? Idx : -1;
+}
+
+int cChannels::GetNextNormal(int Idx)
+{
+ cChannel *channel = Get(++Idx);
+ while (channel && channel->GroupSep())
+ channel = Get(++Idx);
+ return channel ? Idx : -1;
+}
+
+void cChannels::ReNumber( void )
+{
+ int Number = 0;
+ cChannel *ch = (cChannel *)First();
+ while (ch) {
+ if (!ch->GroupSep())
+ ch->SetNumber(++Number);
+ ch = (cChannel *)ch->Next();
+ }
+ maxNumber = Number;
+}
+
+cChannel *cChannels::GetByNumber(int Number)
+{
+ cChannel *channel = (cChannel *)First();
+ while (channel) {
+ if (!channel->GroupSep() && channel->Number() == Number)
+ return channel;
+ channel = (cChannel *)channel->Next();
+ }
+ return NULL;
+}
+
+cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
+{
+ cChannel *channel = (cChannel *)First();
+ while (channel) {
+ if (!channel->GroupSep() && channel->Sid() == ServiceId)
+ return channel;
+ channel = (cChannel *)channel->Next();
+ }
+ return NULL;
+}
+
+bool cChannels::SwitchTo(int Number)
+{
+ cChannel *channel = GetByNumber(Number);
+ return channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true);
+}
+
+const char *cChannels::GetChannelNameByNumber(int Number)
+{
+ cChannel *channel = GetByNumber(Number);
+ return channel ? channel->Name() : NULL;
+}
diff --git a/channels.conf b/channels.conf
index e1e89c3..3d27214 100644
--- a/channels.conf
+++ b/channels.conf
@@ -1,186 +1,186 @@
-RTL:12188:h:0:27500:163:104:105:0:12003
-Sat.1:12480:v:0:27500:1791:1792:34:0:46
-Pro-7:12480:v:0:27500:255:256;257:32:0:898
-RTL2:12188:h:0:27500:166:128:68:0:12020
-ARD:11837:h:0:27500:101:102:104:0:28106
-BR3:11837:h:0:27500:201:202:204:0:28107
-Hessen-3:11837:h:0:27500:301:302:304:0:28108
-N3:12110:h:0:27500:2401:2402:2404:0:28224
-SR3:11837:h:0:27500:501:502:504:0:28110
-WDR:11837:h:0:27500:601:602:604:0:28111
-BR-alpha:11837:h:0:27500:701:702:704:0:28112
-SWR BW:11837:h:0:27500:801:802:804:0:28113
-Phoenix:11837:h:0:27500:901:902:904:0:28114
-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: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
-Super RTL:12188:h:0:27500:165:120:65:0:12040
-VOX:12188:h:0:27500:167:136:71:0:12060
-DW TV:10788:v:0:22000:305:306:0:0:8905
-Kabel 1:12480:v:0:27500:511:512:33:0:899
-Neun Live:12480:v:0:27500:767:768:35:0:897
-DSF:12480:v:0:27500:1023:1024:0:0:900
-HOT:12480:v:0:27500:1279:1280:0:0:40
-Bloomberg TV Germany:12551:v:0:22000:162:99:0:0:12160
-Bloomberg TV France:11817:v:0:27500:163:92:0:0:8004
-Bloomberg TV Spain:12168:v:0:27500:167:112:0:0:12721
-Sky News:12552:v:0:22000:305:306:0:0:3995
-Fox Kids Netherlands:12574:h:0:22000:163:92:0:0:5020
-Alice:12610:v:0:22000:162:96:0:0:12200
-n-tv:12669:v:0:22000:162:96:55:0:12730
-Grand Tourisme:12670:v:0:22000:289:290:0:0:17300
-TW1:12692:h:0:22000:166:167:0:0:13013
-Eurosport:11954:h:0:27500:410:420:0:0:28009
-EinsExtra:12110:h:0:27500:101:102:0:0:28201
-EinsFestival:12110:h:0:27500:201:202:0:0:28202
-EinsMuXx:12110:h:0:27500:301:302:0:0:28203
-ZDF Theaterkanal:11954:h:0:27500:1110:1120:0:0:28016
-ZDF.doku:11954:h:0:27500:660:670:0:0:28014
-MDR:12110:h:0:27500:401:402:404:0:28204
-ORB:12110:h:0:27500:501:502:504:0:28205
-B1:12110:h:0:27500:601:602:604:0:28206
-ARD Online-Kanal:12722:h:0:22000:0:701:0:0:0
+RTL:12188:h:S19.2E:27500:163:104:105:0:12003
+Sat.1:12480:v:S19.2E:27500:1791:1792:34:0:46
+Pro-7:12480:v:S19.2E:27500:255:256;257:32:0:898
+RTL2:12188:h:S19.2E:27500:166:128:68:0:12020
+ARD:11837:h:S19.2E:27500:101:102:104:0:28106
+BR3:11837:h:S19.2E:27500:201:202:204:0:28107
+Hessen-3:11837:h:S19.2E:27500:301:302:304:0:28108
+N3:12110:h:S19.2E:27500:2401:2402:2404:0:28224
+SR3:11837:h:S19.2E:27500:501:502:504:0:28110
+WDR:11837:h:S19.2E:27500:601:602:604:0:28111
+BR-alpha:11837:h:S19.2E:27500:701:702:704:0:28112
+SWR BW:11837:h:S19.2E:27500:801:802:804:0:28113
+Phoenix:11837:h:S19.2E:27500:901:902:904:0:28114
+ZDF:11954:h:S19.2E:27500:110:120:130:0:28006
+3sat:11954:h:S19.2E:27500:210:220:230:0:28007
+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
+VOX:12188:h:S19.2E:27500:167:136:71:0:12060
+DW TV:10788:v:S19.2E:22000:305:306:0:0:8905
+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 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
+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
+EinsExtra:12110:h:S19.2E:27500:101:102:0:0:28201
+EinsFestival:12110:h:S19.2E:27500:201:202:0:0:28202
+EinsMuXx:12110:h:S19.2E:27500:301:302:0:0:28203
+ZDF Theaterkanal:11954:h:S19.2E:27500:1110:1120:0:0:28016
+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:0:27500:255:256:0:101:8
-Premiere 1:11797:h:0:27500:511:512,513;515:0:101:10
-Premiere 2:11797:h:0:27500:1791:1792,1793;1795:0:101:11
-Premiere 3:11797:h:0:27500:2303:2304:0:101:43
-Premiere 4:11797:h:0:27500:767:768:0:101:9
-Premiere 5:11797:h:0:27500:1279:1280:0:101:29
-Premiere 6:11797:h:0:27500:1535:1536:0:101:41
-Premiere 7:11797:h:0:27500:1023:1024:0:101:20
-13th Street:11758:h:0:27500:2303:2304:0:101:42
-Studio Universal:12090:V:0:27500:255:256:0:101:36
-Premiere Serie:12031:h:0:27500:1023:1024:0:101:16
-Disney Channel:12090:V:0:27500:767:768:0:101:34
-Premiere Nostalgie:12031:h:0:27500:2559:2560:0:101:516
-Discovery Channel:12031:h:0:27500:1791:1792:0:101:14
-Planet:12090:v:0:27500:1279:1280:0:101:13
-Fox Kids:11758:h:0:27500:1279:1280:0:101:28
-Junior:11758:h:0:27500:255:256:0:101:19
-K-Toon:11758:h:0:27500:511:512:0:101:12
-Krimi&Co:12031:h:0:27500:1535:1536:0:101:23
-Goldstar TV:11758:h:0:27500:3839:3840:0:101:518
-Classica:11758:h:0:27500:767:768:0:101:15
-Sonnenklar TV:12090:V:0:27500:1023:1024:0:0:32
+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
+Premiere 2:11797:h:S19.2E:27500:1791:1792,1793;1795:0:101:11
+Premiere 3:11797:h:S19.2E:27500:2303:2304:0:101:43
+Premiere 4:11797:h:S19.2E:27500:767:768:0:101:9
+Premiere 5:11797:h:S19.2E:27500:1279:1280:0:101:29
+Premiere 6:11797:h:S19.2E:27500:1535:1536:0:101:41
+Premiere 7:11797:h:S19.2E:27500:1023:1024:0:101:20
+13th Street:11758:h:S19.2E:27500:2303:2304:0:101:42
+Studio Universal:12090:v:S19.2E:27500:255:256:0:101:36
+Premiere Serie:12031:h:S19.2E:27500:1023:1024:0:101:16
+Disney Channel:12090:v:S19.2E:27500:767:768:0:101:34
+Premiere Nostalgie:12031:h:S19.2E:27500:2559:2560:0:101:516
+Discovery Channel:12031:h:S19.2E:27500:1791:1792:0:101:14
+Planet:12090:v:S19.2E:27500:1279:1280:0:101:13
+Fox Kids:11758:h:S19.2E:27500:1279:1280:0:101:28
+Junior:11758:h:S19.2E:27500:255:256:0:101:19
+K-Toon:11758:h:S19.2E:27500:511:512:0:101:12
+Krimi&Co:12031:h:S19.2E:27500:1535:1536:0:101:23
+Goldstar TV:11758:h:S19.2E:27500:3839:3840:0:101:518
+Classica:11758:h:S19.2E:27500:767:768:0:101:15
+Sonnenklar TV:12090:v:S19.2E:27500:1023:1024:0:0:32
:Premiere Direkt
-Premiere Direkt 1A:12031:h:0:27500:511:512,513;515:0:101:177
-Premiere Direkt 1B:11719:h:0:27500:1023:1024,1025;1027:0:101:182
-Premiere Direkt 2A:12031:h:0:27500:255:256;259:0:101:176
-Premiere Direkt 2B:11719:h:0:27500:767:768;769:0:101:181
-Premiere Direkt 3A:11719:h:0:27500:511:512;515:0:101:180
-Premiere Direkt 3B:11719:h:0:27500:1279:1280;1283:0:101:183
-Premiere Direkt 4A:12031:h:0:27500:2815:2816:0:101:18
-:#Premiere Direkt 4B:12070:h:0:27500:1535:1536:0:101:216
+Premiere Direkt 1A:12031:h:S19.2E:27500:511:512,513;515:0:101:177
+Premiere Direkt 1B:11719:h:S19.2E:27500:1023:1024,1025;1027:0:101:182
+Premiere Direkt 2A:12031:h:S19.2E:27500:255:256;259:0:101:176
+Premiere Direkt 2B:11719:h:S19.2E:27500:767:768;769:0:101:181
+Premiere Direkt 3A:11719:h:S19.2E:27500:511:512;515:0:101:180
+Premiere Direkt 3B:11719:h:S19.2E:27500:1279:1280;1283:0:101:183
+Premiere Direkt 4A:12031:h:S19.2E:27500:2815:2816:0:101:18
+:#Premiere Direkt 4B:12070:h:S19.2E:27500:1535:1536:0:101:216
:PW Erotic
-Beate-Uhse.TV:11758:h:0:27500:1023:1024:0:101:21
-Premiere Erotik 1:12031:h:0:27500:1279:1280:0:101:513
-Premiere Erotik 2:11719:h:0:27500:1535:1536:0:101:778
-Premiere Erotik 3:11719:h:0:27500:1791:1792:0:101:779
-Premiere Erotik 4:11719:h:0:27500:3583:3584:0:101:780
+Beate-Uhse.TV:11758:h:S19.2E:27500:1023:1024:0:101:21
+Premiere Erotik 1:12031:h:S19.2E:27500:1279:1280:0:101:513
+Premiere Erotik 2:11719:h:S19.2E:27500:1535:1536:0:101:778
+Premiere Erotik 3:11719:h:S19.2E:27500:1791:1792:0:101:779
+Premiere Erotik 4:11719:h:S19.2E:27500:3583:3584:0:101:780
:Sportsworld
-Premiere Sport 1:11720:h:0:27500:255:256,257:0:101:17
-Premiere Sport 2:12031:h:0:27500:3839:3840:0:101:27
+Premiere Sport 1:11720:h:S19.2E:27500:255:256,257:0:101:17
+Premiere Sport 2:12031:h:S19.2E:27500:3839:3840:0:101:27
:Formel 1
-:#Supersignal:12070:h:0:27500:255:256:0:101:211
-:#Cockpitkanal:12070:h:0:27500:511:512:0:101:212
-:#Boxengasse:12070:h:0:27500:767:768:0:101:213
-:#Verfolgerfeld:12070:h:0:27500:1023:1024:0:101:214
-:#Infokanal:12070:h:0:27500:1279:1280:0:101:215
-Multikanal:11720:h:0:27500:255:256:0:101:17
+:#Supersignal:12070:h:S19.2E:27500:255:256:0:101:211
+:#Cockpitkanal:12070:h:S19.2E:27500:511:512:0:101:212
+:#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
: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
+N24:12480:v:S19.2E:27500:2047:2048:0:0:47
+CNBC:11954:h:S19.2E:27500:510:520:0:0:28010
+Liberty TV.com:12610:v:S19.2E:22000:941:943,942:0:0:12199
:Premiere Bundesliga
-BL-Konferenz:12031:h:0:27500:2303:2304,2305:0:101:210
-BuLi 1:11719:h:0:27500:255:256,257:0:101:17
-BuLi 2:11719:h:0:27500:2047:2048,2049:0:101:240
-BuLi 3:11719:h:0:27500:2303:2304,2305:0:101:241
-BuLi 4:11719:h:0:27500:2559:2560,2561:0:101:242
-BuLi 5:11719:h:0:27500:2815:2816,2817:0:101:243
-BuLi 6:11719:h:0:27500:3071:3072,3073:0:101:244
-BuLi 7:11719:h:0:27500:3327:3328,3329:0:101:245
-BuLi 8:12031:h:0:27500:3071:3072,3073:0:101:208
-BuLi 9:12031:h:0:27500:3327:3328,3329:0:101:209
+BL-Konferenz:12031:h:S19.2E:27500:2303:2304,2305:0:101:210
+BuLi 1:11719:h:S19.2E:27500:255:256,257:0:101:17
+BuLi 2:11719:h:S19.2E:27500:2047:2048,2049:0:101:240
+BuLi 3:11719:h:S19.2E:27500:2303:2304,2305:0:101:241
+BuLi 4:11719:h:S19.2E:27500:2559:2560,2561:0:101:242
+BuLi 5:11719:h:S19.2E:27500:2815:2816,2817:0:101:243
+BuLi 6:11719:h:S19.2E:27500:3071:3072,3073:0:101:244
+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:0:27500:305:321:0:0:20601
-Mosaico:11934:v:0:27500:165:100:0:0:29010
-Andalucia TV:11934:v:0:27500:166:104:0:0:29011
-TVC Internacional:11934:v:0:27500:167:108:0:0:0
-Nasza TV:11992:h:0:27500:165:98:0:0:0
-WishLine test:12012:v:0:27500:163:90:0:0:0
-Pro 7 Austria:12051:v:0:27500:161:84:0:0:20002
-Kabel 1 Schweiz:12051:v:0:27500:162:163:0:0:20003
-Kabel 1 Austria:12051:v:0:27500:166:167:0:0:20004
-Pro 7 Schweiz:12051:v:0:27500:289:290:0:0:20001
-Kiosque:12129:v:0:27500:160:80:0:0:0
-KTO:11739:v:0:27500:163:90:0:0:8304
-TCM:12168:v:0:27500:160:80:0:0:0
-Cartoon Network France & Spain:12168:v:0:27500:161:84:0:0:0
-TVBS Europe:12168:v:0:27500:162:88:0:0:0
-TVBS Europe:12168:v:0:27500:162:89:0:0:0
-Travel:12168:v:0:27500:163:92:0:0:0
-TCM Espania:12168:v:0:27500:164:96:0:0:0
-MTV Spain:12168:v:0:27500:167:112:0:0:0
-TCM France:12168:v:0:27500:169:64:0:0:0
-RTL2 CH:12188:h:0:27500:164:112:0:0:0
-La Cinquieme:12207:v:0:27500:160:80:0:0:8501
-LCP:12207:v:0:27500:165:100:0:0:8506
-Post Filial TV:12226:h:0:27500:255:256:0:0:0
-Canal Canaris:12246:v:0:27500:160:80:0:0:0
-Canal Canaris:12246:v:0:27500:160:81:0:0:0
-Canal Canaris:12246:v:0:27500:160:82:0:0:0
-Canal Canaris:12246:v:0:27500:160:83:0:0:0
-AB Moteurs:12266:h:0:27500:160:80:0:0:17000
-AB Channel 1:12266:h:0:27500:161:84:0:0:0
-Taquilla 0:12285:v:0:27500:165:100:0:0:0
-CSAT:12324:v:0:27500:160:80:0:0:0
-Mosaique:12324:v:0:27500:162:88:0:0:0
-Mosaique 2:12324:v:0:27500:163:92:0:0:0
-Mosaique 3:12324:v:0:27500:164:96:0:0:0
-Le Sesame C+:12324:v:0:27500:165:1965:0:0:0
-FEED:12344:h:0:27500:163:92:0:0:0
-RTM 1:12363:v:0:27500:162:96:0:0:0
-ESC 1:12363:v:0:27500:163:104:0:0:0
-TV5 Europe:12363:v:0:27500:164:112:0:0:0
-TV7 Tunisia:12363:v:0:27500:166:128:0:0:0
-ARTE:12363:v:0:27500:167:137:0:0:0
-RAI Uno:10788:v:0:22000:289:290:0:0:9004
-RTP International:12363:v:0:27500:300:301:0:0:0
-Fashion TV:12402:v:0:27500:163:92:0:0:0
-VideoService:12422:h:0:27500:255:256:0:0:0
-Beta Research promo:12422:h:0:27500:1023:1024:0:0:0
-Canal Canarias:12441:v:0:27500:160:80:0:0:0
-Fitur:12441:v:0:27500:514:662:0:0:0
-Astra Info 1:12552:v:0:22000:164:112:0:0:0
-Astra Info 2:12552:v:0:22000:165:120:0:0:0
-Astra Vision 1:12552:v:0:22000:168:144:0:0:0
-Astra Vision 1:12552:v:0:22000:168:145:0:0:0
-Astra Vision 1:12552:v:0:22000:168:146:0:0:0
-Astra Vision 1:12552:v:0:22000:168:147:0:0:0
-Astra Vision 1:12552:v:0:22000:168:148:0:0:0
-Astra Vision 1:12552:v:0:22000:168:149:0:0:0
-Astra Vision 1:12552:v:0:22000:168:150:0:0:0
-RTL Tele Letzebuerg:12552:v:0:22000:168:144,146:0:0:3994
-Astra Mosaic:12552:v:0:22000:175:176:0:0:0
-MHP test:12604:h:0:22000:5632:0:0:0:0
-VERONICA:12574:h:0:22000:161:84:0:0:5010
-VH1 Classic:12699:v:0:22000:3071:3072:0:0:28647
-MTV 2 Pop:12699:v:0:22000:3081:3082:0:0:28648
-Via 1 - Schöner Reisen:12148:h:0:27500:511:512:0:0:44
-Video Italia:12610:v:0:22000:121:122:0:0:12220
-AC 3 promo:12670:v:0:22000:308:256:0:0:0
-ORF/ZDF:12699:h:0:22000:506:507:0:0:13012
-VIVA:12670:v:0:22000:309:310:0:0:12732
-VIVA2:12552:v:0:22000:171:172:0:0:12120
-MTV German:12699:v:0:22000:3031:3032:0:0:28643
-IFA-TV:10832:h:0:22000:132:133:32:0:7251
-QVC Germany:12552:v:0:22000:165:166:0:0:12100
-TANGOTV:10832:h:1:22000:61:62:0:0:61920
+:#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
+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
+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
+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
+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
+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
+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
+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 5b147fe..e96cd6a 100644
--- a/channels.conf.cable
+++ b/channels.conf.cable
@@ -1,184 +1,209 @@
-:Fernsehprogramme
-Das Erste:410:h:0:6900:101:102:111:0:28106
-ZDF:394:h:0:6900:110:120:130:0:28006
-3sat:394:h:0:6900:210:220:230:0:28007
-arte:410:h:0:6900:401:402:404:0:28109
-EuroNews:394:h:0:6900:2221:2233:768:0:28015
-ZDF.info:394:h:0:6900:610:620:0:0:28011
-ZDF.doku:394:h:0:6900:660:670:0:0:28014
-ZDF Theaterkanal:394:h:0:6900:1110:1120:130:0:28016
-EinsExtra:426:h:0:6900:101:102:0:0:28201
-EinsFestival:426:h:0:6900:201:202:0:0:28202
-EinsMuXx:426:h:0:6900:301:302:0:0:28203
-Phoenix:410:h:0:6900:901:902:0:0:28114
-Eurosport:394:h:0:6900:410:420:430:0:28009
-DW-tv:610:h:0:6900:634:632:0:0:6101
-CNBC:394:h:0:6900:510:520:530:0:28010
+Das Erste:410:M64:C:6900:101:102:104:0:28106
+ZDF:394:M64:C:6900:110:120:130:0:28006
+3sat:394:M64:C:6900:210:220:230:0:28007
+arte:410:M64:C:6900:401:402:404:0:28109
+ZDF.info:394:M64:C:6900:610:620:0:0:28011
+ZDF.doku:394:M64:C:6900:660:670:0:0:28014
+ZDF Theaterkanal:394:M64:C:6900:1110:1120:130:0:28016
+EinsExtra:426:M64:C:6900:101:102:0:0:28201
+EinsFestival:426:M64:C:6900:201:202:0:0:28202
+EinsMuXx:426:M64:C:6900:301:302:0:0:28203
+Phoenix:410:M64:C:6900:901:902:904:0:28114
+EuroNews:394:M64:C:6900:2221:2233:768:0:28015
+CNBC:394:M64:C:6900:510:520:530:0:28010
+Eurosport:394:M64:C:6900:410:420:430:0:28009
:Regionalprogramme
-WDR FERNSEHEN:410:h:0:6900:601:602:604:0:28111
-B1 Berlin:426:h:0:6900:601:602,603:604:0:28206
-ORB-Fernsehen:426:h:0:6900:501:502:504:0:28205
-MDR FERNSEHEN:426:h:0:6900:401:402:404:0:28204
-SR Fernsehen Suedwest:410:h:0:6900:501:502:504:0:28110
-SuedWest BW:410:h:0:6900:801:802:804:0:28113
-SuedWest RP:426:h:0:6900:3101:3102:3104:0:28231
-BR-alpha:410:h:0:6900:701:702:704:0:28112
-N3:426:h:0:6900:2401:2402:2404:0:28224
-hessen fernsehen:410:h:0:6900:301:302:304:0:28108
-Bayerisches FS:410:h:0:6900:201:202:204:0:28107
-Test-R:410:h:0:6900:901:902:104:0:28130
-:Premiere Hauptprogramme
-Premiere START:370:C:0:6900:255:256:32:101:8
-Premiere 1:370:C:0:6900:511:512:0:101:10
-Premiere 2:370:C:0:6900:1791:1792:0:101:11
-Premiere 3:370:C:0:6900:2303:2304:0:101:43
-Premiere 4:370:C:0:6900:767:768:0:101:9
-Premiere 5:370:C:0:6900:1279:1280:0:101:29
-Premiere 6:370:C:0:6900:1535:1536:0:101:41
-Premiere 7:370:C:0:6900:1023:1024:0:101:20
-Premiere SERIE:378:C:0:6900:1023:1024:0:101:16
-Premiere Nostalgie:378:C:0:6900:2559:2560:0:101:516
-13 TH STREET:354:C:0:6900:2303:2304:0:101:42
-Stundio Universal:402:C:0:6900:1050:1054:0:101:36
-Krimi &Co:378:C:0:6900:1535:1536:0:101:23
-Disney Channel:402:C:0:6900:1030:1034:0:101:34
-Discovery Channel:378:C:0:6900:1791:1792:0:101:14
-Fox Kids:354:C:0:6900:1279:1280:0:101:28
-Junior:354:C:0:6900:255:256:0:101:19
-K-TOON:354:C:0:6900:511:512:0:101:12
-GOLDSTAR TV:354:C:0:6900:3839:3840:0:101:518
-CLASSICA:354:C:0:6900:767:768:0:101:15
+B1 Berlin:426:M64:C:6900:601:602:604:0:28206
+ORB-Fernsehen:426:M64:C:6900:501:502:504:0:28205
+N3:426:M64:C:6900:2401:2402:2404:0:28224
+MDR FERNSEHEN:426:M64:C:6900:401:402:404:0:28204
+WDR FERNSEHEN:410:M64:C:6900:601:602:604:0:28111
+hessen fernsehen:410:M64:C:6900:301:302:304:0:28108
+BR-alpha:410:M64:C:6900:701:702:704:0:28112
+Bayerisches FS:410:M64:C:6900:201:202:204:0:28107
+SR Fernsehen Suedwest:410:M64:C:6900:501:502:504:0:28110
+SuedWest BW:410:M64:C:6900:801:802:804:0:28113
+SuedWest RP:426:M64:C:6900:3101:3102:3104:0:28231
+:Hauptprogramme Premiere
+Premiere START:370:M64:C:6900:255:256:32:101:8
+Premiere 1:370:M64:C:6900:511:512;515:0:101:10
+Premiere 2:370:M64:C:6900:1791:1792;1795:0:101:11
+Premiere 3:370:M64:C:6900:2303:2304:0:101:43
+Premiere 4:370:M64:C:6900:767:768:0:101:9
+Premiere 5:370:M64:C:6900:1279:1280:0:101:29
+Premiere 6:370:M64:C:6900:1535:1536:0:101:41
+Premiere 7:370:M64:C:6900:1023:1024:0:101:20
+Premiere SERIE:378:M64:C:6900:1023:1024:0:101:16
+Premiere Nostalgie:378:M64:C:6900:2559:2560:0:101:516
+13 TH STREET:354:M64:C:6900:2303:2304:0:101:42
+Stundio Universal:402:M64:C:6900:1050:1054:0:101:36
+Krimi &Co:378:M64:C:6900:1535:1536:0:101:23
+Disney Channel:402:M64:C:6900:1030:1034:0:101:34
+Discovery Channel:378:M64:C:6900:1791:1792:0:101:14
+PLANET:354:M64:C:6900:1791:1792:0:101:13
+Fox Kids:354:M64:C:6900:1279:1280:0:101:28
+Junior:354:M64:C:6900:255:256:0:101:19
+K-TOON:354:M64:C:6900:511:512:0:101:12
+HEIMATKANAL:354:M64:C:6900:1535:1536:0:101:22
+GOLDSTAR TV:354:M64:C:6900:3839:3840:0:101:518
+CLASSICA:354:M64:C:6900:767:768:0:101:15
:Mediavision
-Bloomberg:346:h:0:6900:811:812:0:101:50701
-Fashion TV:346:h:0:6900:821:822:0:101:50702
-Einstein:346:h:0:6900:623:624:0:101:50719
-Extreme Sport:346:h:0:6900:801:802:0:101:50700
-LANDSCAPE:346:h:0:6900:831:832:0:101:50703
-Single TV:346:h:0:6900:525:526:0:101:50706
-Leitseite:346:h:0:6900:2254:0:0:0:5004
-BET ON JAZZ:346:h:0:6900:841:842:0:101:50704
-:Digit. Bouquet"Kabel Berlin"
-Parlamentsfernsehen:610:C:0:6900:33:36:47:0:6100
-DW-tv:610:C:0:6900:634:632:0:0:6101
-Kanal 7:610:C:0:6900:49:52:0:101:6103
-Euronews:610:C:0:6900:597:592,591:0:101:6104
-Vh1 - Classic:610:h:0:6900:604:603:0:101:6106
-Travel:610:C:0:6900:595:594:0:101:6105
-Nuvolari:618:C:0:6900:1011:1012:0:101:50101
-Marco Polo:618:C:0:6900:1021:1022:0:101:50102
-Alice:618:C:0:6900:1031:1032:0:101:50103
-Leonardo:618:C:0:6900:1041:1042:0:101:50104
-Club:618:C:0:6900:1051:1052:0:101:50105
-Avante:618:C:0:6900:1061:1062:0:101:50106
-Expo 24*7:618:C:0:6900:1071:1072:0:101:50107
-Innergy:618:C:0:6900:0:0:0:101:50108
-BBC Prime:618:C:0:6900:1091:1092:0:101:50109
-Eurosport News:618:C:0:6900:1101:1102:0:101:50110
+Bloomberg:346:M64:C:6900:811:812:0:101:50701
+Fashion TV:346:M64:C:6900:821:822:0:101:50702
+Einstein:346:M64:C:6900:623:624:0:101:50719
+Extreme Sport:346:M64:C:6900:801:802:0:101:50700
+LANDSCAPE:346:M64:C:6900:831:832:0:101:50703
+:DIGIKABEL D
+Avante:113:M64:C:6900:741:742,743:0:101:53404
+BBC Prime:113:M64:C:6900:761:762:763:101:53406
+Club:113:M64:C:6900:711:712,713:0:101:53401
+Eurosport News:113:M64:C:6900:771:772:0:101:53407
+BibelTV:113:M64:C:6900:731:732:0:1:53403
+Liberty TV:113:M64:C:6900:721:722,723:0:101:53402
+TW1:113:M64:C:6900:751:752:0:101:53405
+MTV Base:113:M64:C:6900:781:782:0:101:53408
+:DIGIKABEL INT
+Canal 24 Horas:121:M64:C:6900:991:992:0:101:53509
+Gala TV:121:M64:C:6900:931:932:0:101:53503
+Kanal 7:121:M64:C:6900:941:942:0:101:53504
+Rai 1:121:M64:C:6900:951:952:0:101:53505
+Rai 2:121:M64:C:6900:961:962:0:101:53506
+Rai 3:121:M64:C:6900:971:972:0:101:53507
+Show TV:121:M64:C:6900:911:912:0:101:53501
+TGRT:121:M64:C:6900:921:922:0:101:53502
+TVEi:121:M64:C:6900:981:982:0:101:53508
+:DIGIKABEL SO
+Fox Kids:121:M64:C:6900:931:932,933:0:101:53523
+Kanal 7:121:M64:C:6900:941:942:0:101:53524
+Show TV:121:M64:C:6900:911:912:0:101:53521
+TGRT:121:M64:C:6900:921:922:0:101:53522
+:DIGIKABEL SW
+Canal 24 Horas:121:M64:C:6900:991:992:0:101:53535
+Rai 1:121:M64:C:6900:951:952:0:101:53531
+Rai 2:121:M64:C:6900:961:962:0:101:53532
+Rai 3:121:M64:C:6900:971:972:0:101:53533
+TVEi:121:M64:C:6900:981:982:0:101:53534
:Diverse TV-Sender
-TV Polonia:434:h:0:6900:641:642:0:101:53204
-Kanal D:434:h:0:6900:651:652:0:101:53205
-RTP international:434:h:0:6900:661:662:0:101:53206
-ERT-Sat:434:h:0:6900:691:692:0:101:53209
-CNE:434:h:0:6900:4056:4057:0:101:53208
-ZEE TV:442:h:0:6900:517:773:0:101:53301
-NTV i:442:h:0:6900:514:515:0:101:53302
-ATV:434:h:0:6900:631:632:0:0:53203
-TW1:610:h:0:6900:6106:6107:0:0:6106
-Channel71:386:C:0:6900:1791:1792:0:101:33
+Sonnenklar TV:402:M64:C:6900:0:0:0:101:32
+TV Polonia:434:M64:C:6900:641:642:0:101:53204
+Kanal D:434:M64:C:6900:651:652:0:101:53205
+RTP international:434:M64:C:6900:661:662:0:101:53206
+ERT-Sat:434:M64:C:6900:691:692:0:101:53209
+CNE:434:M64:C:6900:4056:4057:0:101:53208
+ZEE TV:442:M64:C:6900:517:773:0:101:53301
+NTV i:442:M64:C:6900:514:515:0:101:53302
+ATV:434:M64:C:6900:631:632:0:101:53203
+TW1:610:M64:C:6900:6106:6107:0:101:6106
+:Digit. Bouquet "Kabel Berlin"
+Parlamentsfernsehen:610:M64:C:6900:33:36:47:0:6100
+DW-tv:610:M64:C:6900:634:632:0:0:6101
+Kanal 7:610:M64:C:6900:49:52:0:101:6103
+Euronews:610:M64:C:6900:597:592:0:101:6104
+Travel:610:M64:C:6900:595:594:0:101:6105
+VH1 Classic:610:M64:C:6900:604:603:0:101:6106
+Nuvolari:618:M64:C:6900:1011:1012:0:101:50101
+Alice:618:M64:C:6900:1031:1032:0:101:50103
+Leonardo:618:M64:C:6900:1041:1042:0:101:50104
+Club:618:M64:C:6900:1051:1052:0:101:50105
+Avante:618:M64:C:6900:1061:1062:0:101:50106
+BBC Prime:618:M64:C:6900:1091:1092:0:101:50109
+Eurosport News:618:M64:C:6900:1101:1102:0:101:50110
:Premiere Sport
-PREMIERE SPORT 1:362:C:0:6900:255:256,257:0:101:17
-PREMIERE SPORT 2:378:C:0:6900:3839:3840,3841:0:101:27
+PREMIERE SPORT 1:362:M64:C:6900:255:256,258:0:101:17
+PREMIERE SPORT 2:378:M64:C:6900:3839:3840,3841:0:101:27
:Premiere Bundesliga
-Bundesliga Konferenz:378:C:0:6900:2303:2304,2305:0:101:210
-Bundesliga Spiel 1:362:C:0:6900:255:256,257:0:101:17
-Bundesliga Spiel 2:362:C:0:6900:2047:2048,2049:0:101:240
-Bundesliga Spiel 3:362:C:0:6900:2303:2304,2305:0:101:241
-Bundesliga Spiel 4:362:C:0:6900:2559:2560,2561:0:101:242
-Bundesliga Spiel 5:362:C:0:6900:2815:2816,2817:0:101:243
-Bundesliga Spiel 6:362:C:0:6900:3071:3072,3073:0:101:244
-Bundesliga Spiel 7:362:C:0:6900:3327:3328,3329:0:101:245
-Bundesliga Spiel 8:378:C:0:6900:3071:3072,3073:0:101:208
-Bundesliga Spiel 9:378:C:0:6900:3327:3328,3329:0:101:209
+BuLi Opt 1:362:M64:C:6900:255:256:0:101:17
+BuLi Opt 2:362:M64:C:6900:2047:2048:0:101:240
+BuLi Opt 3:362:M64:C:6900:2303:2304:0:101:241
+BuLi Opt 4:362:M64:C:6900:2559:2560:0:101:242
+BuLi Opt 5:362:M64:C:6900:2815:2816:0:101:243
+BuLi Opt 6:362:M64:C:6900:3071:3072:0:101:244
+BuLi Opt 7:362:M64:C:6900:3327:3328:0:101:245
+BuLi Opt 8:378:M64:C:6900:3071:3072:0:101:208
+BuLi Opt 9:378:M64:C:6900:3327:3328:0:101:209
+BuLi Opt 10:378:M64:C:6900:2303:2304:0:101:210
+:Premiere CL
+UEFA CL 1:362:M64:C:6900:255:256,257:0:101:17
+UEFA CL 2:386:M64:C:6900:255:256:0:101:211
:Premiere Formel 1
-F1 Multi:362:h:0:6900:255:256,257:0:101:17
-F1 Supersignal:386:h:0:6900:255:256,257:0:101:211
-F1 Cockpit:386:h:0:6900:511:512,513:0:101:212
-F1 Boxen:386:h:0:6900:767:768,769:0:101:213
-F1 Verfolger:386:h:0:6900:1023:1024,1025:0:101:214
-F1 Info:386:h:0:6900:1279:1280,1281:0:101:215
+F1 Portal 1:362:M64:C:6900:255:256:0:101:17
+F1 Supersignal:362:M64:C:6900:2047:2048:0:101:240
+F1 Cockpit Kanal:362:M64:C:6900:2303:2304:0:101:241
+F1 Boxengasse:362:M64:C:6900:2559:2560:0:101:242
+F1 Verfolgerfeld:362:M64:C:6900:2815:2816:0:101:243
+F1 Infokanal:362:M64:C:6900:3071:3072:0:101:244
:Premiere Direkt 1
-PREMIERE DIREKT 1A:362:C:0:6900:1023:1024,1025:0:101:182
-PREMIERE DIREKT 1B:378:C:0:6900:511:512,513:0:101:177
+PREMIERE DIREKT 1A:378:M64:C:6900:511:512,513;515:0:101:177
+PREMIERE DIREKT 1B:362:M64:C:6900:1023:1024,1025;1027:0:101:182
:Premiere Direkt 2
-PREMIERE DIREKT 2A:378:C:0:6900:255:256,257:0:101:176
-PREMIERE DIREKT 2B:362:C:0:6900:767:768,769:0:101:181
+PREMIERE DIREKT 2A:378:M64:C:6900:255:256,257;259:0:101:176
+PREMIERE DIREKT 2B:362:M64:C:6900:767:768,769;771:0:101:181
:Premiere Direkt 3
-PREMIERE DIREKT 3A:362:C:0:6900:511:512,513:0:101:180
-PREMIERE DIREKT 3B:362:C:0:6900:1279:1280,1281:0:101:183
+PREMIERE DIREKT 3A:362:M64:C:6900:1279:1280,1281;1283:0:101:183
+PREMIERE DIREKT 3B:362:M64:C:6900:511:512,513;515:0:101:180
:Premiere Direkt 4
-PREMIERE DIREKT 4A:378:C:0:6900:2815:2816,2817:0:101:18
-PREMIERE DIREKT 4B:386:C:0:6900:1535:1536,1537:0:101:216
+PREMIERE DIREKT 4A:378:M64:C:6900:2815:2816,2817:0:101:18
+PREMIERE DIREKT 4B:386:M64:C:6900:1535:1536,1537:0:101:216
:Premiere Erotik
-BEATE-UHSE.TV:354:C:0:6900:1023:1024:0:101:21
-PREMIERE EROTIK 1:378:C:0:6900:1279:1280:0:101:513
-PREMIERE EROTIK 2:362:C:0:6900:1535:1536:0:101:778
-PREMIERE EROTIK 3:362:C:0:6900:1791:1792:0:101:779
-PREMIERE EROTIK 4:362:C:0:6900:3583:3584:0:101:780
-:Radioprogramme
-Fritz:426:h:0:6900:1:901:0:0:28209
-HR XXL:410:h:0:6900:1:3501:0:0:28125
-JUMP:426:h:0:6900:1:1001:0:0:28210
-SPUTNIK:426:h:0:6900:1:1201:0:0:28212
-RADIOmultikulti:426:h:0:6900:1:1301:0:0:28213
-DLR-Berlin:394:h:0:6900:1:710:0:0:28012
-DLF-Köln:394:h:0:6900:1:810:0:0:28013
-Österreich 1:394:h:0:6900:1:169:0:0:28017
-100,6:354:h:0:6900:1:1312:0:0:161
-Bayern 4 Klassik:410:h:0:6900:1:3001:0:0:28120
-B5 aktuell:410:h:0:6900:1:3101:0:0:28121
-Bremen 2:410:h:0:6900:1:3801:0:0:28128
-Bayern 1:410:h:0:6900:1:3601:0:0:28126
-NDR 4 Info:410:h:0:6900:1:3701:0:0:28127
-SR 1:410:h:0:6900:1:3901:0:0:28129
-hr-klassik:410:h:0:6900:1:3401:0:0:28124
-hr2:410:h:0:6900:1:3301:0:0:28123
-hr-chronos:410:h:0:6900:1:3201:0:0:28122
-Radio 3:426:h:0:6900:1:701:0:0:28207
-MDR KULTUR:426:h:0:6900:1:801:0:0:28208
-MDR info:426:h:0:6900:1:1101:0:0:28211
-SWR-2:426:h:0:6900:1:1401:0:0:28214
-WDR3:426:h:0:6900:1:1501:0:0:28215
-WDR Radio 5:426:h:0:6900:1:1601:0:0:28216
-:verschlüsselte Radioprogramme
-ALTERNATIVE ROCK:370:C:0:6900:1:800:0:101:151
-CLASSIC ROCK:370:C:0:6900:1:544:0:101:154
-DANCE:370:C:0:6900:1:816:0:101:152
-LOVE SONGS:370:C:0:6900:1:352:0:101:163
-GOLD:370:C:0:6900:1:576:0:101:159
-OLD GOLD:370:C:0:6900:1:304:0:101:165
-SOUL CLASSICS:370:C:0:6900:1:400:0:101:157
-EASY LISTENING:370:C:0:6900:1:384:0:101:162
-DEUTSCHE HITS:370:C:0:6900:1:592:0:101:156
-SCHLAGER:370:C:0:6900:1:320:0:101:166
-VOLKSMUSIK:362:C:0:6900:1:336:0:101:167
-COUNTRY:362:C:0:6900:1:352:0:101:153
-FILMMUSIK:362:C:0:6900:1:368:0:101:155
-MUSICALS:362:C:0:6900:1:384:0:101:164
-JAZZ:362:C:0:6900:1:656:0:101:149
-KLASSIK POPUL04R:378:C:0:6900:1:592:0:101:145
-ORCHESTRALE WERKE:378:C:0:6900:1:608:0:101:146
-BAROCK:378:C:0:6900:1:640:0:101:148
-OPER:378:C:0:6900:1:624:0:101:147
-TÜRK MÜZIGI:378:C:0:6900:1:560:0:101:158
-HITLISTE:370:C:0:6900:1:784:0:101:150
-Radio GoldStar:354:C:0:6900:1:368:0:101:171
-All Jazz:442:C:0:6900:1:535:0:101:53350
-Cristal New Age:442:C:0:6900:1:536:0:101:53351
-Movie Sounds:442:C:0:6900:1:537:0:101:53352
-Sinfonica:442:C:0:6900:1:538:0:101:53353
-Opernfestival:442:C:0:6900:1:539:0:101:53354
-Barock Fantasie:442:C:0:6900:1:540:0:101:53355
-Musica Camerata:442:C:0:6900:1:541:0:101:53356
-Musica Antica:442:C:0:6900:1:542:0:101:53357
-Adagio:442:C:0:6900:1:543:0:101:53358
-Jazz legends:442:C:0:6900:1:544:0:101:53359
+BEATE-UHSE.TV:354:M64:C:6900:1023:1024:0:101:21
+PREMIERE EROTIK 1:378:M64:C:6900:1279:1280:0:101:513
+PREMIERE EROTIK 2:362:M64:C:6900:1535:1536:0:101:778
+PREMIERE EROTIK 3:362:M64:C:6900:1791:1792:0:101:779
+PREMIERE EROTIK 4:362:M64:C:6900:3583:3584:0:101:780
+:Radio-Sender (FTV)
+Fritz:426:M64:C:6900:8191:901:0:0:28209
+SPUTNIK:426:M64:C:6900:8191:1201:0:0:28212
+HR XXL:410:M64:C:6900:8191:3501:0:0:28125
+JUMP:426:M64:C:6900:8191:1001:0:0:28210
+MDR info:426:M64:C:6900:8191:1101:0:0:28211
+MDR KULTUR:426:M64:C:6900:8191:801:0:0:28208
+Radio 3:426:M64:C:6900:8191:701:0:0:28207
+RADIOmultikulti:426:M64:C:6900:8191:1301:0:0:28213
+SWR2:426:M64:C:6900:8191:1401:0:0:28214
+WDR 3:426:M64:C:6900:8191:1501:0:0:28215
+WDR Radio 5:426:M64:C:6900:8191:1601:0:0:28216
+Bayern 4 Klassik:410:M64:C:6900:8191:3001:0:0:28120
+B5 aktuell:410:M64:C:6900:8191:3101:0:0:28121
+NordwestRadio:410:M64:C:6900:8191:3801:0:0:28128
+Bayern 1:410:M64:C:6900:8191:3601:0:0:28126
+NDR Info:410:M64:C:6900:8191:3701:0:0:28127
+SR 1:410:M64:C:6900:8191:3901:0:0:28129
+hr-klassik:410:M64:C:6900:8191:3401:0:0:28124
+hr2:410:M64:C:6900:8191:3301:0:0:28123
+hr-chronos:410:M64:C:6900:8191:3201:0:0:28122
+DLF-Köln:394:M64:C:6900:8191:810:0:0:28013
+DLR-Berlin:394:M64:C:6900:8191:710:0:0:28012
+Österreich 1:394:M64:C:6900:8191:169:0:0:28017
+Radio GoldStar:354:M64:C:6900:8191:368:0:0:171
+:Radio-Sender (PPV)
+ALTERNATIVE ROCK:370:M64:C:6900:8191:544:0:101:154
+DEUTSCHE HITS:370:M64:C:6900:8191:800:0:101:151
+HITLISTE:370:M64:C:6900:8191:784:0:101:150
+HIP HOP/R&B:370:M64:C:6900:8191:576:0:101:159
+DANCE:370:M64:C:6900:8191:304:0:101:165
+HARD ROCK:370:M64:C:6900:8191:816:0:101:152
+LOVE SONGS:370:M64:C:6900:8191:592:0:101:156
+FILM & MUSICAL:378:M64:C:6900:8191:592:0:101:145
+EASY LISTENING:378:M64:C:6900:8191:608:0:101:146
+JAZZ:378:M64:C:6900:8191:640:0:101:148
+KLASSIK POPULÄR:378:M64:C:6900:8191:624:0:101:147
+ORCHESTRALE WERKE:378:M64:C:6900:8191:560:0:101:158
+CLASSIC ROCK:370:M64:C:6900:8191:352:0:101:163
+VOLKSMUSIK:370:M64:C:6900:8191:400:0:101:157
+SCHLAGER:370:M64:C:6900:8191:384:0:101:162
+GOLD:370:M64:C:6900:8191:320:0:101:166
+OLD GOLD:362:M64:C:6900:8191:336:0:101:167
+SOUL CLASSICS:362:M64:C:6900:8191:352:0:101:153
+LATIN:362:M64:C:6900:8191:368:0:101:155
+NEW COUNTRY:362:M64:C:6900:8191:384:0:101:164
+COUNTRY:362:M64:C:6900:8191:656:0:101:149
+All Jazz:442:M64:C:6900:8191:535:0:101:53350
+Cristal New Age:442:M64:C:6900:8191:536:0:101:53351
+Movie Sounds:442:M64:C:6900:8191:537:0:101:53352
+Sinfonica:442:M64:C:6900:8191:538:0:101:53353
+Opernfestival:442:M64:C:6900:8191:539:0:101:53354
+Barock Fantasie:442:M64:C:6900:8191:540:0:101:53355
+Musica Camerata:442:M64:C:6900:8191:541:0:101:53356
+Musica Antica:442:M64:C:6900:8191:542:0:101:53357
+Adagio:442:M64:C:6900:8191:543:0:101:53358
+Jazz legends:442:M64:C:6900:8191:544:0:101:53359
diff --git a/channels.conf.terr b/channels.conf.terr
index 81c0581..14362a1 100644
--- a/channels.conf.terr
+++ b/channels.conf.terr
@@ -10,11 +10,22 @@ 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
: DVB-T Berlin Germany
-RTL 1:778000:V:0:27500:160:80:0:1:1
-RTL 2:778000:V:0:27500:161:82:0:1:2
-Super RTL:778000:V:0:27500:162:84:0:1:3
-VOX:778000:V:0:27500:165:81:0:1:4
-SAT 1:714000:V:0:27500:160:80:0:1:18
-PRO 7:714000:V:0:27500:161:82:0:1:19
-KABEL 1:714000:V:0:27500:162:84:0:1:20
-N24:714000:V:0:27500:163:86:0:1:21
+PRO 7:714000:I0C23D0M16B8T8G8Y0:T:27500:161:82:83:0:19
+SAT 1:714000:I0C23D0M16B8T8G8Y0:T:27500:160:80:81:0:18
+RTL:778000:I0C23D0M16B8T8G8Y0:T:27500:160:80:0:0:1
+RTL 2:778000:I0C23D0M16B8T8G8Y0:T:27500:161:82:0:0:2
+Super RTL:778000:I0C23D0M16B8T8G8Y0:T:27500:162:84:0:0:3
+VOX:778000:I0C23D0M16B8T8G8Y0:T:27500:163:86:0:0:4
+KABEL 1:714000:I0C23D0M16B8T8G8Y0:T:27500:162:84:0:0:20
+MTV:674000:I0C23D0M16B8T2G8Y0:T:27500:161:82:83:0:27
+VIVA/arte:674000:I0C23D0M16B8T2G8Y0:T:27500:163:86:87:0:29
+N-TV:650000:I0C12D0M16B8T2G8Y0:T:27500:160:80:81:0:6
+N24:714000:I0C23D0M16B8T8G8Y0:T:27500:163:86:0:0:21
+Eurosport:674000:I0C23D0M16B8T2G8Y0:T:27500:160:80:81:0:26
+FAB:674000:I0C23D0M16B8T2G8Y0:T:27500:162:84:84:0:28
+ARD:602000:I0C23D0M16B8T8G8Y0:T:27500:208:209:667:0:4
+ZDF:730000:I0C23D0M16B8T2G8Y0:T:27500:110:120:130:0:22
+ZDF-docukanal:730000:I0C23D0M16B8T2G8Y0:T:27500:660:670:130:0:24
+ZDF-info:730000:I0C23D0M16B8T2G8Y0:T:27500:610:620:130:0:23
+EinsMuXx:650000:I0C12D0M16B8T2G8Y0:T:27500:161:82:0:0:7
+EinsFestival:602000:I0C23D0M16B8T8G8Y0:T:27500:80:81:0:0:2
diff --git a/channels.h b/channels.h
new file mode 100644
index 0000000..8a784f7
--- /dev/null
+++ b/channels.h
@@ -0,0 +1,124 @@
+/*
+ * channels.h: Channel handling
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: channels.h 1.1 2002/10/05 13:53:15 kls Exp $
+ */
+
+#ifndef __CHANNELS_H
+#define __CHANNELS_H
+
+#include "config.h"
+#include "sources.h"
+#include "tools.h"
+
+#define ISTRANSPONDER(f1, f2) (abs((f1) - (f2)) < 4) //XXX
+
+struct tChannelParameterMap {
+ int userValue;
+ int driverValue;
+ };
+
+//XXX into cChannel???
+int MapToUser(int Value, const tChannelParameterMap *Map);
+int MapToDriver(int Value, const tChannelParameterMap *Map);
+int UserIndex(int Value, const tChannelParameterMap *Map);
+int DriverIndex(int Value, const tChannelParameterMap *Map);
+
+extern const tChannelParameterMap InversionValues[];
+extern const tChannelParameterMap BandwidthValues[];
+extern const tChannelParameterMap CoderateValues[];
+extern const tChannelParameterMap ModulationValues[];
+extern const tChannelParameterMap TransmissionValues[];
+extern const tChannelParameterMap GuardValues[];
+extern const tChannelParameterMap HierarchyValues[];
+
+class cChannel : public cListObject {
+ friend class cMenuEditChannel;
+private:
+ static char *buffer;
+ static const char *ToText(cChannel *Channel);
+ enum { MaxChannelName = 32 }; // 31 chars + terminating 0!
+ char name[MaxChannelName];
+ int frequency; // MHz
+ int source;
+ int srate;
+ int vpid;
+ int apid1, apid2;
+ int dpid1, dpid2;
+ int tpid;
+ int ca;
+ int sid;
+ int number; // Sequence number assigned on load
+ bool groupSep;
+ //XXX
+ char polarization;
+ int inversion;
+ int bandwidth;
+ int coderateH;
+ int coderateL;
+ int modulation;
+ int transmission;
+ int guard;
+ int hierarchy;
+ const char *ParametersToString(void);
+ bool StringToParameters(const char *s);
+public:
+ cChannel(void);
+ cChannel(const cChannel *Channel);
+ const char *ToText(void);
+ bool Parse(const char *s);
+ bool Save(FILE *f);
+ const char *Name(void) const { return name; }
+ int Frequency(void) const { return frequency; }
+ int Source(void) const { return source; }
+ int Srate(void) const { return srate; }
+ int Vpid(void) const { return vpid; }
+ int Apid1(void) const { return apid1; }
+ int Apid2(void) const { return apid2; }
+ int Dpid1(void) const { return dpid1; }
+ int Dpid2(void) const { return dpid2; }
+ int Tpid(void) const { return tpid; }
+ int Ca(void) const { return ca; }
+ int Sid(void) const { return sid; }
+ 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; }
+ int CoderateH(void) const { return coderateH; }
+ int CoderateL(void) const { return coderateL; }
+ int Modulation(void) const { return modulation; }
+ 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; }
+ };
+
+class cChannels : public cConfig<cChannel> {
+protected:
+ int maxNumber;
+public:
+ cChannels(void) { maxNumber = 0; }
+ virtual bool Load(const char *FileName, bool AllowComments = false);
+ int GetNextGroup(int Idx); // Get next channel group
+ int GetPrevGroup(int Idx); // Get previous channel group
+ int GetNextNormal(int Idx); // Get next normal channel (not group)
+ void ReNumber(void); // Recalculate 'number' based on channel type
+ cChannel *GetByNumber(int Number);
+ cChannel *GetByServiceID(unsigned short ServiceId);
+ const char *GetChannelNameByNumber(int Number);
+ bool SwitchTo(int Number);
+ int MaxNumber(void) { return maxNumber; }
+ };
+
+extern cChannels Channels;
+
+#endif //__CHANNELS_H
diff --git a/config.c b/config.c
index e5a5609..24c1438 100644
--- a/config.c
+++ b/config.c
@@ -4,12 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.c 1.106 2002/09/28 09:43:41 kls Exp $
+ * $Id: config.c 1.107 2002/10/03 10:06:55 kls Exp $
*/
#include "config.h"
#include <ctype.h>
#include <stdlib.h>
+#include "channels.h" //XXX timers!
#include "i18n.h"
#include "interface.h"
#include "plugin.h"
@@ -19,116 +20,6 @@
// format characters in order to allow any number of blanks after a numeric
// value!
-// -- cChannel ---------------------------------------------------------------
-
-char *cChannel::buffer = NULL;
-
-cChannel::cChannel(void)
-{
- *name = 0;
-}
-
-cChannel::cChannel(const cChannel *Channel)
-{
- strcpy(name, Channel ? Channel->name : "Pro7");
- frequency = Channel ? Channel->frequency : 12480;
- polarization = Channel ? Channel->polarization : 'v';
- diseqc = Channel ? Channel->diseqc : 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;
- pnr = Channel ? Channel->pnr : 0;
- groupSep = Channel ? Channel->groupSep : false;
-}
-
-const char *cChannel::ToText(cChannel *Channel)
-{
- char buf[MaxChannelName * 2];
- char *s = Channel->name;
- if (strchr(s, ':')) {
- s = strcpy(buf, s);
- strreplace(s, ':', '|');
- }
- free(buffer);
- if (Channel->groupSep)
- asprintf(&buffer, ":%s\n", s);
- else {
- char apidbuf[32];
- char *q = apidbuf;
- q += snprintf(q, sizeof(apidbuf), "%d", Channel->apid1);
- if (Channel->apid2)
- q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->apid2);
- if (Channel->dpid1 || Channel->dpid2)
- q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ";%d", Channel->dpid1);
- if (Channel->dpid2)
- q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->dpid2);
- *q = 0;
- asprintf(&buffer, "%s:%d:%c:%d:%d:%d:%s:%d:%d:%d\n", s, Channel->frequency, Channel->polarization, Channel->diseqc, Channel->srate, Channel->vpid, apidbuf, Channel->tpid, Channel->ca, Channel->pnr);
- }
- return buffer;
-}
-
-const char *cChannel::ToText(void)
-{
- return ToText(this);
-}
-
-bool cChannel::Parse(const char *s)
-{
- char *buffer = NULL;
- if (*s == ':') {
- if (*++s) {
- strn0cpy(name, s, MaxChannelName);
- groupSep = true;
- number = 0;
- }
- else
- return false;
- }
- else {
- groupSep = false;
- char *apidbuf = NULL;
- int fields = sscanf(s, "%a[^:]:%d :%c:%d :%d :%d :%a[^:]:%d :%d :%d ", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apidbuf, &tpid, &ca, &pnr);
- apid1 = apid2 = 0;
- dpid1 = dpid2 = 0;
- if (apidbuf) {
- char *p = strchr(apidbuf, ';');
- if (p)
- *p++ = 0;
- sscanf(apidbuf, "%d ,%d ", &apid1, &apid2);
- if (p)
- sscanf(p, "%d ,%d ", &dpid1, &dpid2);
- free(apidbuf);
- }
- else
- return false;
- if (fields >= 9) {
- if (fields == 9) {
- // allow reading of old format
- pnr = ca;
- ca = tpid;
- tpid = 0;
- }
- strn0cpy(name, buffer, MaxChannelName);
- free(buffer);
- }
- else
- return false;
- }
- strreplace(name, '|', ':');
- return true;
-}
-
-bool cChannel::Save(FILE *f)
-{
- return fprintf(f, ToText()) > 0;
-}
-
// -- cTimer -----------------------------------------------------------------
char *cTimer::buffer = NULL;
@@ -139,7 +30,7 @@ cTimer::cTimer(bool Instant)
recording = pending = false;
active = Instant ? taActInst : taInactive;
cChannel *ch = Channels.GetByNumber(cDevice::CurrentChannel());
- channel = ch ? ch->number : 0;
+ channel = ch ? ch->Number() : 0;
time_t t = time(NULL);
struct tm tm_r;
struct tm *now = localtime_r(&t, &tm_r);
@@ -156,7 +47,7 @@ cTimer::cTimer(bool Instant)
firstday = 0;
summary = NULL;
if (Instant && ch)
- snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : ch->name);
+ snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : ch->Name());
}
cTimer::cTimer(const cEventInfo *EventInfo)
@@ -165,7 +56,7 @@ cTimer::cTimer(const cEventInfo *EventInfo)
recording = pending = false;
active = true;
cChannel *ch = Channels.GetByServiceID(EventInfo->GetServiceID());
- channel = ch ? ch->number : 0;
+ channel = ch ? ch->Number() : 0;
time_t tstart = EventInfo->GetTime();
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
tstart -= Setup.MarginStart * 60;
@@ -573,89 +464,6 @@ bool cCaDefinition::Parse(const char *s)
cCommands Commands;
-// -- cChannels --------------------------------------------------------------
-
-cChannels Channels;
-
-bool cChannels::Load(const char *FileName, bool AllowComments)
-{
- if (cConfig<cChannel>::Load(FileName, AllowComments)) {
- ReNumber();
- return true;
- }
- return false;
-}
-
-int cChannels::GetNextGroup(int Idx)
-{
- cChannel *channel = Get(++Idx);
- while (channel && !channel->groupSep)
- channel = Get(++Idx);
- return channel ? Idx : -1;
-}
-
-int cChannels::GetPrevGroup(int Idx)
-{
- cChannel *channel = Get(--Idx);
- while (channel && !channel->groupSep)
- channel = Get(--Idx);
- return channel ? Idx : -1;
-}
-
-int cChannels::GetNextNormal(int Idx)
-{
- cChannel *channel = Get(++Idx);
- while (channel && channel->groupSep)
- channel = Get(++Idx);
- return channel ? Idx : -1;
-}
-
-void cChannels::ReNumber( void )
-{
- int Number = 0;
- cChannel *ch = (cChannel *)First();
- while (ch) {
- if (!ch->groupSep)
- ch->number = ++Number;
- ch = (cChannel *)ch->Next();
- }
- maxNumber = Number;
-}
-
-cChannel *cChannels::GetByNumber(int Number)
-{
- cChannel *channel = (cChannel *)First();
- while (channel) {
- if (!channel->groupSep && channel->number == Number)
- return channel;
- channel = (cChannel *)channel->Next();
- }
- return NULL;
-}
-
-cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
-{
- cChannel *channel = (cChannel *)First();
- while (channel) {
- if (!channel->groupSep && channel->pnr == ServiceId)
- return channel;
- channel = (cChannel *)channel->Next();
- }
- return NULL;
-}
-
-bool cChannels::SwitchTo(int Number)
-{
- cChannel *channel = GetByNumber(Number);
- return channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true);
-}
-
-const char *cChannels::GetChannelNameByNumber(int Number)
-{
- cChannel *channel = GetByNumber(Number);
- return channel ? channel->name : NULL;
-}
-
// -- cTimers ----------------------------------------------------------------
cTimers Timers;
diff --git a/config.h b/config.h
index dc04305..2da1420 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.129 2002/09/29 10:42:17 kls Exp $
+ * $Id: config.h 1.131 2002/10/05 09:58:58 kls Exp $
*/
#ifndef __CONFIG_H
@@ -20,7 +20,7 @@
#include "eit.h"
#include "tools.h"
-#define VDRVERSION "1.1.11"
+#define VDRVERSION "1.1.12"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
@@ -32,34 +32,6 @@
#define MaxFileName 256
-#define ISTRANSPONDER(f1, f2) (abs((f1) - (f2)) < 4)
-
-class cChannel : public cListObject {
-private:
- static char *buffer;
- static const char *ToText(cChannel *Channel);
-public:
- enum { MaxChannelName = 32 }; // 31 chars + terminating 0!
- char name[MaxChannelName];
- int frequency; // MHz
- char polarization;
- int diseqc;
- int srate;
- int vpid;
- int apid1, apid2;
- int dpid1, dpid2;
- int tpid;
- int ca;
- int pnr;
- int number; // Sequence number assigned on load
- bool groupSep;
- cChannel(void);
- cChannel(const cChannel *Channel);
- const char *ToText(void);
- bool Parse(const char *s);
- bool Save(FILE *f);
- };
-
enum eTimerActive { taInactive = 0,
taActive = 1,
taInstant = 2,
@@ -193,7 +165,7 @@ public:
if (l->Parse(buffer))
Add(l);
else {
- esyslog("error in %s, line %d\n", fileName, line);
+ esyslog("ERROR: error in %s, line %d\n", fileName, line);
delete l;
result = false;
break;
@@ -229,23 +201,6 @@ public:
}
};
-class cChannels : public cConfig<cChannel> {
-protected:
- int maxNumber;
-public:
- cChannels(void) { maxNumber = 0; }
- virtual bool Load(const char *FileName, bool AllowComments = false);
- int GetNextGroup(int Idx); // Get next channel group
- int GetPrevGroup(int Idx); // Get previous channel group
- int GetNextNormal(int Idx); // Get next normal channel (not group)
- void ReNumber(void); // Recalculate 'number' based on channel type
- cChannel *GetByNumber(int Number);
- cChannel *GetByServiceID(unsigned short ServiceId);
- const char *GetChannelNameByNumber(int Number);
- bool SwitchTo(int Number);
- int MaxNumber(void) { return maxNumber; }
- };
-
class cTimers : public cConfig<cTimer> {
public:
cTimer *GetTimer(cTimer *Timer);
@@ -265,7 +220,6 @@ public:
const cCaDefinition *Get(int Number);
};
-extern cChannels Channels;
extern cTimers Timers;
extern cCommands Commands;
extern cSVDRPhosts SVDRPhosts;
diff --git a/device.c b/device.c
index 12166a8..473b178 100644
--- a/device.c
+++ b/device.c
@@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.22 2002/09/28 12:20:22 kls Exp $
+ * $Id: device.c 1.25 2002/10/06 13:49:38 kls Exp $
*/
#include "device.h"
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
+#include "channels.h"
#include "eit.h"
#include "i18n.h"
#include "player.h"
@@ -143,7 +144,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool *NeedsDe
|| !d->Receiving() // ...the one we have is not receiving...
&& (device[i]->Priority() < d->Priority() // ...this one has an even lower Priority, or...
|| device[i]->Priority() == d->Priority() // ...same Priority...
- && device[i]->ProvidesCa(Channel->ca) < d->ProvidesCa(Channel->ca) // ...but this one provides fewer Ca values
+ && device[i]->ProvidesCa(Channel->Ca()) < d->ProvidesCa(Channel->Ca()) // ...but this one provides fewer Ca values
)
)
) {
@@ -275,6 +276,11 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On)
return false;
}
+bool cDevice::ProvidesSource(int Source) const
+{
+ return false;
+}
+
bool cDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
{
return false;
@@ -283,11 +289,13 @@ bool cDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Needs
bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView)
{
if (LiveView)
- isyslog("switching to channel %d", Channel->number);
+ isyslog("switching to channel %d", Channel->Number());
for (int i = 3; i--;) {
switch (SetChannel(Channel, LiveView)) {
case scrOk: return true;
- case scrNotAvailable: return false;
+ case scrNotAvailable: if (Interface)
+ Interface->Error(tr("Channel not available!"));
+ return false;
case scrNoTransfer: if (Interface)
Interface->Error(tr("Can't start Transfer Mode!"));
return false;
@@ -305,21 +313,25 @@ bool cDevice::SwitchChannel(int Direction)
if (Direction) {
int n = CurrentChannel() + Direction;
int first = n;
- for (;;) {
- cChannel *channel = Channels.GetByNumber(n);
- if (!channel)
- break;
- if (PrimaryDevice()->SwitchChannel(channel, true)) {
- result = true;
- break;
- }
- n += Direction;
- }
- int d = n - first;
- if (abs(d) == 1)
- dsyslog("skipped channel %d", first);
- else if (d)
- dsyslog("skipped channels %d..%d", first, n - sgn(d));
+ PrimaryDevice()->StopReplay(); // otherwise a running Transfer Mode would block channels
+ cChannel *channel;
+ while ((channel = Channels.GetByNumber(n)) != NULL) {
+ // try only channels which are currently available
+ if (PrimaryDevice()->ProvidesChannel(channel, Setup.PrimaryLimit) || GetDevice(channel, 0))
+ break;
+ n += Direction;
+ }
+ if (channel) {
+ int d = n - first;
+ if (abs(d) == 1)
+ dsyslog("skipped channel %d", first);
+ else if (d)
+ dsyslog("skipped channels %d..%d", first, n - sgn(d));
+ if (PrimaryDevice()->SwitchChannel(channel, true))
+ result = true;
+ }
+ else if (n != first && Interface)
+ Interface->Error(tr("Channel not available!"));
}
return result;
}
@@ -344,7 +356,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (CaDevice) {
cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
if (CaDevice->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()!
- cControl::Launch(new cTransferControl(CaDevice, Channel->vpid, Channel->apid1, 0, 0, 0));//XXX+
+ cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), 0, 0, 0));//XXX+
else
Result = scrNoTransfer;
}
@@ -359,10 +371,10 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (Result == scrOk) {
if (LiveView && IsPrimaryDevice()) {
- cSIProcessor::SetCurrentServiceID(Channel->pnr);
- currentChannel = Channel->number;
+ cSIProcessor::SetCurrentServiceID(Channel->Sid());
+ currentChannel = Channel->Number();
}
- cStatus::MsgChannelSwitch(this, Channel->number); // only report status if channel switch successfull
+ cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
}
return Result;
diff --git a/device.h b/device.h
index b6f4427..9dcf16c 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 1.20 2002/09/28 12:20:34 kls Exp $
+ * $Id: device.h 1.21 2002/10/05 15:18:13 kls Exp $
*/
#ifndef __DEVICE_H
@@ -139,6 +139,8 @@ public:
protected:
static int currentChannel;
public:
+ virtual bool ProvidesSource(int Source) const;
+ // Returns true if this device can provide the given source.
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
// Returns true if this device can provide the given channel.
// In case the device has cReceivers attached to it or it is the primary
diff --git a/diseqc.c b/diseqc.c
new file mode 100644
index 0000000..92b92cb
--- /dev/null
+++ b/diseqc.c
@@ -0,0 +1,136 @@
+/*
+ * diseqc.c: DiSEqC handling
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: diseqc.c 1.1 2002/10/05 13:54:32 kls Exp $
+ */
+
+#include "diseqc.h"
+#include <ctype.h>
+#include "sources.h"
+
+// -- cDiseqc ----------------------------------------------------------------
+
+cDiseqc::cDiseqc(void)
+{
+ commands = NULL;
+ currentAction = NULL;;
+ parsing = false;
+ numCodes = 0;
+}
+
+cDiseqc::~cDiseqc()
+{
+ free(commands);
+}
+
+bool cDiseqc::Parse(const char *s)
+{
+ bool result = false;
+ char *sourcebuf = NULL;
+ int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands);
+ if (fields == 4)
+ commands = NULL; //XXX Apparently sscanf() doesn't work correctly if the last %a argument results in an empty string
+ if (4 <= fields && fields <= 5) {
+ source = cSource::FromString(sourcebuf);
+ if (Sources.Get(source)) {
+ polarization = toupper(polarization);
+ if (polarization == 'V' || polarization == 'H') {
+ parsing = true;
+ bool Start = true;
+ while (Execute(Start) != daNone)
+ Start = false;
+ parsing = false;
+ result = !commands || currentAction && !*currentAction;
+ }
+ else
+ esyslog("ERROR: unknown polarization '%c'", polarization);
+ }
+ else
+ esyslog("ERROR: unknown source '%s'", sourcebuf);
+ }
+ free(sourcebuf);
+ return result;
+}
+
+char *cDiseqc::Wait(char *s)
+{
+ char *p = NULL;
+ errno = 0;
+ int n = strtol(s, &p, 10);
+ if (!errno && p != s && n >= 0) {
+ if (!parsing)
+ usleep(n * 1000);
+ return p;
+ }
+ esyslog("ERROR: illegal value for wait time in '%s'", s - 1);
+ return NULL;
+}
+
+char *cDiseqc::Codes(char *s)
+{
+ char *e = strchr(s, ']');
+ if (e) {
+ numCodes = 0;
+ char *t = s;
+ char *p = s;
+ while (t < e) {
+ if (numCodes < MaxDiseqcCodes) {
+ errno = 0;
+ int n = strtol(t, &p, 16);
+ if (!errno && p != t && 0 <= n && n <= 255) {
+ codes[numCodes++] = n;
+ t = skipspace(p);
+ }
+ else {
+ esyslog("ERROR: illegal code at '%s'", t);
+ return NULL;
+ }
+ }
+ else {
+ esyslog("ERROR: too many codes in code sequence '%s'", s - 1);
+ return NULL;
+ }
+ }
+ return e + 1;
+ }
+ else
+ esyslog("ERROR: missing closing ']' in code sequence '%s'", s - 1);
+ return NULL;
+}
+
+cDiseqc::eDiseqcActions cDiseqc::Execute(bool Start)
+{
+ if (Start)
+ currentAction = commands;
+ while (currentAction && *currentAction) {
+ switch (*currentAction++) {
+ case ' ': break;
+ case 't': return daToneOff;
+ case 'T': return daToneOn;
+ case 'v': return daVoltage13;
+ case 'V': return daVoltage18;
+ case 'A': return daMiniA;
+ case 'B': return daMiniB;
+ case 'W': currentAction = Wait(currentAction); break;
+ case '[': currentAction = Codes(currentAction); return currentAction ? daCodes : daNone;
+ default: return daNone;
+ }
+ }
+ return daNone;
+}
+
+// -- cDiseqcs ---------------------------------------------------------------
+
+cDiseqcs Diseqcs;
+
+cDiseqc *cDiseqcs::Get(int Source, int Frequency, char Polarization)
+{
+ for (cDiseqc *p = First(); p; p = Next(p)) {
+ if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization))
+ return p;
+ }
+ return NULL;
+}
diff --git a/diseqc.conf b/diseqc.conf
new file mode 100644
index 0000000..52222f3
--- /dev/null
+++ b/diseqc.conf
@@ -0,0 +1,30 @@
+# DiSEqC configuration for VDR
+#
+# Format:
+#
+# satellite slof polarization lof command...
+#
+# satellite: one of the 'S' codes defined in sources.conf
+# slof: switch frequency of LNB; the first entry with
+# an slof greater than the actual transponder
+# frequency will be used
+# polarization: V = vertical, H = horizontal
+# lof: the local oscillator frequency to subtract from
+# the actual transponder frequency
+# command:
+# t tone off
+# T tone on
+# v voltage low (13V)
+# V voltage high (18V)
+# A mini A
+# B mini B
+# Wnn wait nn milliseconds (nn may be any positive integer number)
+# [xx ...] hex code sequence (max. 6)
+#
+# The 'command...' part is optional.
+
+S19.2E 11700 V 9750 t v W15 [E0 10 38 F0] W15 A W15 t
+S19.2E 99999 V 10600 t v W15 [E0 10 38 F1] W15 A W15 T
+S19.2E 11700 H 9750 t V W15 [E0 10 38 F2] W15 A W15 t
+S19.2E 99999 H 10600 t V W15 [E0 10 38 F3] W15 A W15 T
+
diff --git a/diseqc.h b/diseqc.h
new file mode 100644
index 0000000..f2b0e99
--- /dev/null
+++ b/diseqc.h
@@ -0,0 +1,60 @@
+/*
+ * diseqc.h: DiSEqC handling
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: diseqc.h 1.1 2002/10/05 13:02:52 kls Exp $
+ */
+
+#ifndef __DISEQC_H
+#define __DISEQC_H
+
+#include "config.h"
+
+class cDiseqc : public cListObject {
+public:
+ enum eDiseqcActions {
+ daNone,
+ daToneOff,
+ daToneOn,
+ daVoltage13,
+ daVoltage18,
+ daMiniA,
+ daMiniB,
+ daCodes,
+ };
+ enum { MaxDiseqcCodes = 6 };
+private:
+ int source;
+ int slof;
+ char polarization;
+ int lof;
+ char *commands;
+ char *currentAction;
+ bool parsing;
+ uchar codes[MaxDiseqcCodes];
+ int numCodes;
+ char *Wait(char *s);
+ char *Codes(char *s);
+public:
+ cDiseqc(void);
+ ~cDiseqc();
+ bool Parse(const char *s);
+ eDiseqcActions Execute(bool Start = false);
+ int Source(void) const { return source; }
+ int Slof(void) const { return slof; }
+ char Polarization(void) const { return polarization; }
+ int Lof(void) const { return lof; }
+ const char *Commands(void) const { return commands; }
+ uchar *Codes(int &NumCodes) { NumCodes = numCodes; return numCodes ? codes : NULL; }
+ };
+
+class cDiseqcs : public cConfig<cDiseqc> {
+public:
+ cDiseqc *Get(int Source, int Frequency, char Polarization);
+ };
+
+extern cDiseqcs Diseqcs;
+
+#endif //__DISEQC_H
diff --git a/dvbdevice.c b/dvbdevice.c
index f337e35..eeaa7b0 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.21 2002/09/29 13:53:26 kls Exp $
+ * $Id: dvbdevice.c 1.22 2002/10/06 09:07:45 kls Exp $
*/
#include "dvbdevice.h"
@@ -31,6 +31,8 @@ extern "C" {
#endif
#include <sys/ioctl.h>
#include <sys/mman.h>
+#include "channels.h"
+#include "diseqc.h"
#include "dvbosd.h"
#include "player.h"
#include "receiver.h"
@@ -124,7 +126,9 @@ cDvbDevice::cDvbDevice(int n)
else
esyslog("ERROR: can't open DVB device %d", n);
- frequency = 0;
+ source = -1;
+ frequency = -1;
+ diseqcCommands = NULL;
}
cDvbDevice::~cDvbDevice()
@@ -344,18 +348,33 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
return true;
}
+bool cDvbDevice::IsTunedTo(const cChannel *Channel) const
+{
+ return source == Channel->Source() && frequency == Channel->Frequency();
+}
+
+bool cDvbDevice::ProvidesSource(int Source) const
+{
+ int type = Source & cSource::st_Mask;
+ return type == cSource::stNone
+ || type == cSource::stCable && frontendType == FE_QAM
+ || type == cSource::stSat && frontendType == FE_QPSK
+ || type == cSource::stTerr && frontendType == FE_OFDM;
+ return true;
+}
+
bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
{
bool result = false;
bool hasPriority = Priority < 0 || Priority > this->Priority();
bool needsDetachReceivers = true;
- if (ProvidesCa(Channel->ca)) {
+ if (ProvidesSource(Channel->Source()) && ProvidesCa(Channel->Ca())) {
if (Receiving()) {
- if (frequency == Channel->frequency) {
+ if (IsTunedTo(Channel)) {
needsDetachReceivers = false;
- if (!HasPid(Channel->vpid)) {
- if (Channel->ca > CACONFBASE) {
+ if (!HasPid(Channel->Vpid())) {
+ if (Channel->Ca() > CACONFBASE) {
needsDetachReceivers = true;
result = hasPriority;
}
@@ -394,24 +413,24 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
LiveView = true;
#endif
- bool DoTune = frequency != Channel->frequency; // TODO will be changed when DiSEqC handling is revised
+ bool DoTune = !IsTunedTo(Channel);
bool TurnOffLivePIDs = HasDecoder()
&& (DoTune
- || Channel->ca > CACONFBASE && pidHandles[ptVideo].pid != Channel->vpid // CA channels can only be decrypted in "live" mode
+ || Channel->Ca() > CACONFBASE && pidHandles[ptVideo].pid != Channel->Vpid() // CA channels can only be decrypted in "live" mode
|| IsPrimaryDevice()
&& (LiveView // for a new live view the old PIDs need to be turned off
- || pidHandles[ptVideo].pid == Channel->vpid // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
+ || pidHandles[ptVideo].pid == Channel->Vpid() // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
)
);
bool StartTransferMode = IsPrimaryDevice() && !DoTune
- && (LiveView && HasPid(Channel->vpid) && pidHandles[ptVideo].pid != Channel->vpid // the PID is already set as DMX_PES_OTHER
- || !LiveView && pidHandles[ptVideo].pid == Channel->vpid // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
+ && (LiveView && HasPid(Channel->Vpid()) && pidHandles[ptVideo].pid != Channel->Vpid() // the PID is already set as DMX_PES_OTHER
+ || !LiveView && pidHandles[ptVideo].pid == Channel->Vpid() // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
);
bool TurnOnLivePIDs = HasDecoder() && !StartTransferMode
- && (Channel->ca > CACONFBASE // CA channels can only be decrypted in "live" mode
+ && (Channel->Ca() > CACONFBASE // CA channels can only be decrypted in "live" mode
|| LiveView
);
@@ -452,67 +471,127 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
switch (frontendType) {
case FE_QPSK: { // DVB-S
- // Frequency offsets:
-
- unsigned int freq = Channel->frequency;
- int tone = SEC_TONE_OFF;
+ unsigned int frequency = Channel->Frequency();
- if (freq < (unsigned int)Setup.LnbSLOF) {
- freq -= Setup.LnbFrequLo;
- tone = SEC_TONE_OFF;
+ if (Setup.DiSEqC) {
+ cDiseqc *diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization());
+ if (diseqc) {
+ if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
+#ifndef NEWSTRUCT
+ int SecTone = SEC_TONE_OFF;
+ int SecVolt = SEC_VOLTAGE_13;
+#endif
+ cDiseqc::eDiseqcActions da;
+ for (bool Start = true; (da = diseqc->Execute(Start)) != cDiseqc::daNone; Start = false) {
+ switch (da) {
+#ifdef NEWSTRUCT
+ case cDiseqc::daNone: break;
+ case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+ case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+ case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+ case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+ case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+ case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+ case cDiseqc::daCodes: {
+ int n = 0;
+ uchar *codes = diseqc->Codes(n);
+ if (codes) {
+ struct dvb_diseqc_master_cmd cmd;
+ memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+ cmd.msg_len = n;
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+ }
+ }
+ break;
+#else
+ // This may not work very good with the old driver.
+ // Let's try to emulate the NEWSTRUCT driver's behaviour as good as possible...
+ case cDiseqc::daNone: break;
+ case cDiseqc::daToneOff: CHECK(ioctl(fd_sec, SEC_SET_TONE, SecTone = SEC_TONE_OFF)); break;
+ case cDiseqc::daToneOn: CHECK(ioctl(fd_sec, SEC_SET_TONE, SecTone = SEC_TONE_ON)); break;
+ case cDiseqc::daVoltage13: CHECK(ioctl(fd_sec, SEC_SET_VOLTAGE, SecVolt = SEC_VOLTAGE_13)); break;
+ case cDiseqc::daVoltage18: CHECK(ioctl(fd_sec, SEC_SET_VOLTAGE, SecVolt = SEC_VOLTAGE_18)); break;
+ case cDiseqc::daMiniA:
+ case cDiseqc::daMiniB: {
+ secCmdSequence scmds;
+ memset(&scmds, 0, sizeof(scmds));
+ scmds.voltage = SecVolt;
+ scmds.miniCommand = (da == cDiseqc::daMiniA) ? SEC_MINI_A : SEC_MINI_B;
+ scmds.continuousTone = SecTone;
+ CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
+ }
+ break;
+ case cDiseqc::daCodes: {
+ int n = 0;
+ uchar *codes = diseqc->Codes(n);
+ if (codes && n >= 3 && codes[0] == 0xE0) {
+ secCommand scmd;
+ memset(&scmd, 0, sizeof(scmd));
+ scmd.type = SEC_CMDTYPE_DISEQC;
+ scmd.u.diseqc.addr = codes[1];
+ scmd.u.diseqc.cmd = codes[2];
+ scmd.u.diseqc.numParams = n - 3;
+ memcpy(scmd.u.diseqc.params, &codes[3], min(n - 3, int(sizeof(scmd.u.diseqc.params))));
+
+ secCmdSequence scmds;
+ memset(&scmds, 0, sizeof(scmds));
+ scmds.voltage = SecVolt;
+ scmds.miniCommand = SEC_MINI_NONE;
+ scmds.continuousTone = SecTone;
+ scmds.numCommands = 1;
+ scmds.commands = &scmd;
+
+ CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
+ }
+ }
+ break;
+#endif
+ }
+ }
+ diseqcCommands = diseqc->Commands();
+ }
+ frequency -= diseqc->Lof();
+ }
+ else {
+ esyslog("ERROR: no DiSEqC parameters found for channel %d", Channel->Number());
+ return false;
+ }
}
else {
- freq -= Setup.LnbFrequHi;
- tone = SEC_TONE_ON;
- }
-
+ int tone = SEC_TONE_OFF;
+
+ if (frequency < (unsigned int)Setup.LnbSLOF) {
+ frequency -= Setup.LnbFrequLo;
+ tone = SEC_TONE_OFF;
+ }
+ else {
+ frequency -= Setup.LnbFrequHi;
+ tone = SEC_TONE_ON;
+ }
+ int volt = (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
#ifdef NEWSTRUCT
- Frontend.frequency = freq * 1000UL;
- Frontend.inversion = INVERSION_AUTO;
- Frontend.u.qpsk.symbol_rate = Channel->srate * 1000UL;
- Frontend.u.qpsk.fec_inner = FEC_AUTO;
+ CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+ CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
#else
- Frontend.Frequency = freq * 1000UL;
- Frontend.Inversion = INVERSION_AUTO;
- Frontend.u.qpsk.SymbolRate = Channel->srate * 1000UL;
- Frontend.u.qpsk.FEC_inner = FEC_AUTO;
+ secCmdSequence scmds;
+ memset(&scmds, 0, sizeof(scmds));
+ scmds.voltage = volt;
+ scmds.miniCommand = SEC_MINI_NONE;
+ scmds.continuousTone = tone;
+ CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
#endif
-
- int volt = (Channel->polarization == 'v' || Channel->polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
-
- // DiSEqC:
+ }
#ifdef NEWSTRUCT
- struct dvb_diseqc_master_cmd cmd = { {0xE0, 0x10, 0x38, 0xF0, 0x00, 0x00}, 4};
- cmd.msg[3] = 0xF0 | (((Channel->diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0));
-
- if (Setup.DiSEqC)
- CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
- CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
- if (Setup.DiSEqC) {
- usleep(15 * 1000);
- CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
- usleep(15 * 1000);
- CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, (Channel->diseqc / 4) % 2 ? SEC_MINI_B : SEC_MINI_A));
- usleep(15 * 1000);
- }
- CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+ Frontend.frequency = frequency * 1000UL;
+ Frontend.inversion = SpectralInversion(Channel->Inversion());
+ Frontend.u.qpsk.symbol_rate = Channel->Srate() * 1000UL;
+ Frontend.u.qpsk.fec_inner = CodeRate(Channel->CoderateH());
#else
- secCommand scmd;
- scmd.type = 0;
- scmd.u.diseqc.addr = 0x10;
- scmd.u.diseqc.cmd = 0x38;
- scmd.u.diseqc.numParams = 1;
- scmd.u.diseqc.params[0] = 0xF0 | ((Channel->diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0);
-
- secCmdSequence scmds;
- scmds.voltage = volt;
- scmds.miniCommand = SEC_MINI_NONE;
- scmds.continuousTone = tone;
- scmds.numCommands = Setup.DiSEqC ? 1 : 0;
- scmds.commands = &scmd;
-
- CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
+ Frontend.Frequency = frequency * 1000UL;
+ Frontend.Inversion = SpectralInversion(Channel->Inversion());
+ Frontend.u.qpsk.SymbolRate = Channel->Srate() * 1000UL;
+ Frontend.u.qpsk.FEC_inner = CodeRate(Channel->CoderateH());
#endif
}
break;
@@ -521,17 +600,17 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
// Frequency and symbol rate:
#ifdef NEWSTRUCT
- Frontend.frequency = Channel->frequency * 1000000UL;
- Frontend.inversion = INVERSION_AUTO;
- Frontend.u.qam.symbol_rate = Channel->srate * 1000UL;
- Frontend.u.qam.fec_inner = FEC_AUTO;
- Frontend.u.qam.modulation = QAM_64;
+ Frontend.frequency = Channel->Frequency() * 1000000UL;
+ Frontend.inversion = SpectralInversion(Channel->Inversion());
+ Frontend.u.qam.symbol_rate = Channel->Srate() * 1000UL;
+ Frontend.u.qam.fec_inner = CodeRate(Channel->CoderateH());
+ Frontend.u.qam.modulation = Modulation(Channel->Modulation());
#else
- Frontend.Frequency = Channel->frequency * 1000000UL;
- Frontend.Inversion = INVERSION_AUTO;
- Frontend.u.qam.SymbolRate = Channel->srate * 1000UL;
- Frontend.u.qam.FEC_inner = FEC_AUTO;
- Frontend.u.qam.QAM = QAM_64;
+ Frontend.Frequency = Channel->Frequency() * 1000000UL;
+ Frontend.Inversion = SpectralInversion(Channel->Inversion());
+ Frontend.u.qam.SymbolRate = Channel->Srate() * 1000UL;
+ Frontend.u.qam.FEC_inner = CodeRate(Channel->CoderateH());
+ Frontend.u.qam.QAM = Modulation(Channel->Modulation());
#endif
}
break;
@@ -540,25 +619,25 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
// Frequency and OFDM paramaters:
#ifdef NEWSTRUCT
- Frontend.frequency = Channel->frequency * 1000UL;
- Frontend.inversion = INVERSION_AUTO;
- Frontend.u.ofdm.bandwidth=BANDWIDTH_8_MHZ;
- Frontend.u.ofdm.code_rate_HP = FEC_2_3;
- Frontend.u.ofdm.code_rate_LP = FEC_1_2;
- Frontend.u.ofdm.constellation = QAM_64;
- Frontend.u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
- Frontend.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
- Frontend.u.ofdm.hierarchy_information = HIERARCHY_NONE;
+ Frontend.frequency = Channel->Frequency() * 1000UL;
+ Frontend.inversion = SpectralInversion(Channel->Inversion());
+ Frontend.u.ofdm.bandwidth = BandWidth(Channel->Bandwidth());
+ Frontend.u.ofdm.code_rate_HP = CodeRate(Channel->CoderateH());
+ Frontend.u.ofdm.code_rate_LP = CodeRate(Channel->CoderateL());
+ Frontend.u.ofdm.constellation = Modulation(Channel->Modulation());
+ Frontend.u.ofdm.transmission_mode = TransmitMode(Channel->Transmission());
+ Frontend.u.ofdm.guard_interval = GuardInterval(Channel->Guard());
+ Frontend.u.ofdm.hierarchy_information = Hierarchy(Channel->Hierarchy());
#else
- Frontend.Frequency = Channel->frequency * 1000UL;
- Frontend.Inversion = INVERSION_AUTO;
- Frontend.u.ofdm.bandWidth=BANDWIDTH_8_MHZ;
- Frontend.u.ofdm.HP_CodeRate=FEC_2_3;
- Frontend.u.ofdm.LP_CodeRate=FEC_1_2;
- Frontend.u.ofdm.Constellation=QAM_64;
- Frontend.u.ofdm.TransmissionMode=TRANSMISSION_MODE_2K;
- Frontend.u.ofdm.guardInterval=GUARD_INTERVAL_1_32;
- Frontend.u.ofdm.HierarchyInformation=HIERARCHY_NONE;
+ Frontend.Frequency = Channel->Frequency() * 1000UL;
+ Frontend.Inversion = SpectralInversion(Channel->Inversion());
+ Frontend.u.ofdm.bandWidth = BandWidth(Channel->Bandwidth());
+ Frontend.u.ofdm.HP_CodeRate = CodeRate(Channel->CoderateH());
+ Frontend.u.ofdm.LP_CodeRate = CodeRate(Channel->CoderateL());
+ Frontend.u.ofdm.Constellation = Modulation(Channel->Modulation());
+ Frontend.u.ofdm.TransmissionMode = TransmitMode(Channel->Transmission());
+ Frontend.u.ofdm.guardInterval = GuardInterval(Channel->Guard());
+ Frontend.u.ofdm.HierarchyInformation = Hierarchy(Channel->Hierarchy());
#endif
}
break;
@@ -592,7 +671,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
usleep(10 * 1000);
}
if (!(status & FE_HAS_LOCK)) {
- esyslog("ERROR: channel %d not locked on DVB card %d!", Channel->number, CardIndex() + 1);
+ esyslog("ERROR: channel %d not locked on DVB card %d!", Channel->Number(), CardIndex() + 1);
if (LiveView && IsPrimaryDevice())
cThread::RaisePanic();
return false;
@@ -602,43 +681,44 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
FrontendEvent event;
if (ioctl(fd_frontend, FE_GET_EVENT, &event) >= 0) {
if (event.type != FE_COMPLETION_EV) {
- esyslog("ERROR: channel %d not sync'ed on DVB card %d!", Channel->number, CardIndex() + 1);
+ esyslog("ERROR: channel %d not sync'ed on DVB card %d!", Channel->Number(), CardIndex() + 1);
if (LiveView && IsPrimaryDevice())
cThread::RaisePanic();
return false;
}
}
else
- esyslog("ERROR in frontend get event (channel %d, card %d): %m", Channel->number, CardIndex() + 1);
+ esyslog("ERROR in frontend get event (channel %d, card %d): %m", Channel->Number(), CardIndex() + 1);
}
else
esyslog("ERROR: timeout while tuning on DVB card %d", CardIndex() + 1);
#endif
- frequency = Channel->frequency;
+ source = Channel->Source();
+ frequency = Channel->Frequency();
}
// PID settings:
if (TurnOnLivePIDs) {
- if (!(AddPid(Channel->apid1, ptAudio) && AddPid(Channel->vpid, ptVideo))) {//XXX+ dolby dpid1!!! (if audio plugins are attached)
- esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->number, CardIndex() + 1);
+ if (!(AddPid(Channel->Apid1(), ptAudio) && AddPid(Channel->Vpid(), ptVideo))) {//XXX+ dolby dpid1!!! (if audio plugins are attached)
+ esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
return false;
}
if (IsPrimaryDevice())
- AddPid(Channel->tpid, ptTeletext);
+ AddPid(Channel->Tpid(), ptTeletext);
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
}
else if (StartTransferMode)
- cControl::Launch(new cTransferControl(this, Channel->vpid, Channel->apid1, 0, 0, 0));
+ cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid1(), 0, 0, 0));
// Start setting system time:
if (siProcessor)
- siProcessor->SetCurrentTransponder(Channel->frequency);
+ siProcessor->SetCurrentTransponder(Channel->Frequency());
return true;
}
diff --git a/dvbdevice.h b/dvbdevice.h
index acf569e..df7aa03 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.h 1.11 2002/09/28 12:21:36 kls Exp $
+ * $Id: dvbdevice.h 1.12 2002/10/06 08:57:24 kls Exp $
*/
#ifndef __DVBDEVICE_H
@@ -61,8 +61,12 @@ public:
// Channel facilities
private:
+ int source;
int frequency;
+ const char *diseqcCommands;
+ bool IsTunedTo(const cChannel *Channel) const;
public:
+ virtual bool ProvidesSource(int Source) const;
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
protected:
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
diff --git a/eit.c b/eit.c
index 1e69930..48735df 100644
--- a/eit.c
+++ b/eit.c
@@ -16,15 +16,12 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.c 1.52 2002/09/20 16:24:17 kls Exp $
+ * $Id: eit.c 1.54 2002/10/06 10:31:38 kls Exp $
***************************************************************************/
#include "eit.h"
#include <ctype.h>
#include <fcntl.h>
-#include <fstream.h>
-#include <iomanip.h>
-#include <iostream.h>
#include <limits.h>
#ifdef NEWSTRUCT
#include <linux/dvb/dmx.h>
@@ -40,6 +37,7 @@
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
+#include "channels.h"
#include "config.h"
#include "libdtv/libdtv.h"
#include "videodir.h"
@@ -456,7 +454,7 @@ static void ReportEpgBugFixStats(bool Reset = false)
for (int c = 0; c < p->n; c++) {
cChannel *channel = Channels.GetByServiceID(p->serviceIDs[c]);
if (channel) {
- q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->name);
+ q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name());
delim = ", ";
}
}
@@ -768,7 +766,7 @@ void cSchedule::Dump(FILE *f, const char *Prefix) const
cChannel *channel = Channels.GetByServiceID(uServiceID);
if (channel)
{
- fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->name);
+ fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->Name());
for (cEventInfo *p = Events.First(); p; p = Events.Next(p))
p->Dump(f, Prefix);
fprintf(f, "%sc\n", Prefix);
diff --git a/eitscan.c b/eitscan.c
index 069a133..c29b6b5 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,11 +4,12 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.c 1.7 2002/09/08 11:08:52 kls Exp $
+ * $Id: eitscan.c 1.8 2002/10/05 13:44:35 kls Exp $
*/
#include "eitscan.h"
#include <stdlib.h>
+#include "channels.h"
#include "dvbdevice.h"
cEITScanner::cEITScanner(void)
@@ -28,11 +29,11 @@ cEITScanner::~cEITScanner()
bool cEITScanner::TransponderScanned(cChannel *Channel)
{
for (int i = 0; i < numTransponders; i++) {
- if (transponders[i] == Channel->frequency)
+ if (transponders[i] == Channel->Frequency())
return true;
}
transponders = (int *)realloc(transponders, ++numTransponders * sizeof(int));
- transponders[numTransponders - 1] = Channel->frequency;
+ transponders[numTransponders - 1] = Channel->Frequency();
return false;
}
@@ -66,7 +67,7 @@ void cEITScanner::Process(void)
if (Channel) {
if (!Device->ProvidesChannel(Channel))
break;
- if (Channel->pnr && !TransponderScanned(Channel)) {
+ if (Channel->Sid() && !TransponderScanned(Channel)) {
if (Device == cDevice::PrimaryDevice() && !currentChannel)
currentChannel = Device->CurrentChannel();
Device->SwitchChannel(Channel, false);
diff --git a/i18n.c b/i18n.c
index 81b7717..d8dc3b7 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.93 2002/09/29 12:32:46 kls Exp $
+ * $Id: i18n.c 1.95 2002/10/06 11:31:18 kls Exp $
*
* Translations provided by:
*
@@ -890,21 +890,21 @@ const tI18nPhrase Phrases[] = {
"Polarizare",
"Polarizáció",
},
- { "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
- "DiSEqC",
+ { "Source",
+ "Quelle",
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
},
{ "Srate",
"Srate",
@@ -1034,21 +1034,149 @@ const tI18nPhrase Phrases[] = {
"Criptare",
"CA",
},
- { "Pnr",
- "Pnr",
- "Pnr",
- "Pnr",
- "Pnr",
- "Núm. Progr.",
- "Num. Progr.",
- "Program Id",
- "Ohjelmatunnus",
- "Pnr",
- "Pnr",
- "Pnr",
- "Pnr",
- "Nr. Prog.",
- "Pnr",
+ { "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ "Sid",
+ },
+ { "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ "Inversion",
+ },
+ { "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ "Bandwidth",
+ },
+ { "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ "CoderateH",
+ },
+ { "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ "CoderateL",
+ },
+ { "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ "Modulation",
+ },
+ { "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ "Transmission",
+ },
+ { "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ "Guard",
+ },
+ { "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
+ "Hierarchy",
},
// Timer parameters:
{ "Active",
@@ -1308,6 +1436,22 @@ const tI18nPhrase Phrases[] = {
"Nu mai sunt dispozitive DVB pentru inregistrare!",
"Nincs szabad DVB kártya a felvételhez!",
},
+ { "Channel not available!",
+ "Kanal nicht verfügbar!",
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ "",//TODO
+ },
{ "Channel locked (recording)!",
"Kanal blockiert (zeichnet auf)!",
"Zaklenjen kanal (snemanje)!",
@@ -2723,6 +2867,54 @@ const tI18nPhrase Phrases[] = {
"nu",
"nem",
},
+ { "off",
+ "aus",
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ },
+ { "none",
+ "keine",
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ },
+ { "auto",
+ "auto",
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ "",// TODO
+ },
{ "top",
"oben",
"zgoraj",
diff --git a/interface.c b/interface.c
index 3f1fba8..64c7489 100644
--- a/interface.c
+++ b/interface.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: interface.c 1.55 2002/09/29 12:50:22 kls Exp $
+ * $Id: interface.c 1.56 2002/09/30 15:32:10 kls Exp $
*/
#include "interface.h"
@@ -366,6 +366,7 @@ void cInterface::QueryKeys(cRemote *Remote)
ClearEol(0, 7);
ClearEol(0, 8);
ClearEol(0, 9);
+ Flush();
for (;;) {
Key = cRemote::Get(100);
if (Key == kUp) {
diff --git a/menu.c b/menu.c
index eaf260f..fcd9ba4 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.209 2002/09/29 12:50:47 kls Exp $
+ * $Id: menu.c 1.212 2002/10/06 14:08:44 kls Exp $
*/
#include "menu.h"
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "channels.h"
#include "config.h"
#include "cutter.h"
#include "eit.h"
@@ -21,6 +22,7 @@
#include "plugin.h"
#include "recording.h"
#include "remote.h"
+#include "sources.h"
#include "status.h"
#include "videodir.h"
@@ -53,7 +55,7 @@ void cMenuEditChanItem::Set(void)
char buf[255];
cChannel *channel = Channels.GetByNumber(*value);
if (channel)
- snprintf(buf, sizeof(buf), "%d %s", *value, channel->name);
+ snprintf(buf, sizeof(buf), "%d %s", *value, channel->Name());
else
*buf = 0;
SetValue(buf);
@@ -77,8 +79,8 @@ cMenuEditTranItem::cMenuEditTranItem(const char *Name, int *Value)
transponder = *Value;
cChannel *channel = Channels.First();
while (channel) {
- if (!channel->groupSep && ISTRANSPONDER(channel->frequency, *Value)) {
- number = channel->number;
+ if (!channel->GroupSep() && ISTRANSPONDER(channel->Frequency(), *Value)) {
+ number = channel->Number();
break;
}
channel = (cChannel *)channel->Next();
@@ -95,7 +97,7 @@ eOSState cMenuEditTranItem::ProcessKey(eKeys Key)
number = *value;
cChannel *channel = Channels.GetByNumber(*value);
if (channel)
- transponder = channel->frequency;
+ transponder = channel->Frequency();
*value = transponder;
return state;
}
@@ -391,12 +393,137 @@ eOSState cMenuEditCaItem::ProcessKey(eKeys Key)
return state;
}
+// --- cMenuEditSrcItem ------------------------------------------------------
+
+class cMenuEditSrcItem : public cMenuEditIntItem {
+private:
+ const cSource *source;
+protected:
+ virtual void Set(void);
+public:
+ cMenuEditSrcItem(const char *Name, int *Value);
+ eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditSrcItem::cMenuEditSrcItem(const char *Name, int *Value)
+:cMenuEditIntItem(Name, Value, 0)
+{
+ source = Sources.Get(*Value);
+ Set();
+}
+
+void cMenuEditSrcItem::Set(void)
+{
+ if (source) {
+ char *buffer = NULL;
+ asprintf(&buffer, "%s - %s", cSource::ToString(source->Code()), source->Description());
+ SetValue(buffer);
+ free(buffer);
+ }
+ else
+ cMenuEditIntItem::Set();
+}
+
+eOSState cMenuEditSrcItem::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 (source && source->Prev()) {
+ source = (cSource *)source->Prev();
+ *value = source->Code();
+ }
+ }
+ else if (NORMALKEY(Key) == kRight) {
+ if (source) {
+ if (source->Next())
+ source = (cSource *)source->Next();
+ }
+ else
+ source = Sources.First();
+ if (source)
+ *value = source->Code();
+ }
+ else
+ return state; // we don't call cMenuEditIntItem::ProcessKey(Key) here since we don't accept numerical input
+ Set();
+ state = osContinue;
+ }
+ return state;
+}
+
+// --- cMenuEditMapItem ------------------------------------------------------
+
+class cMenuEditMapItem : public cMenuEditItem {
+protected:
+ int *value;
+ const tChannelParameterMap *map;
+ const char *zeroString;
+ virtual void Set(void);
+public:
+ cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString = NULL);
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
+cMenuEditMapItem::cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString)
+:cMenuEditItem(Name)
+{
+ value = Value;
+ map = Map;
+ zeroString = ZeroString;
+ Set();
+}
+
+void cMenuEditMapItem::Set(void)
+{
+ int n = MapToUser(*value, map);
+ if (n == 999)
+ SetValue(tr("auto"));
+ else if (n == 0 && zeroString)
+ SetValue(zeroString);
+ else if (n >= 0) {
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%d", n);
+ SetValue(buf);
+ }
+ else
+ SetValue("???");
+}
+
+eOSState cMenuEditMapItem::ProcessKey(eKeys Key)
+{
+ eOSState state = cMenuEditItem::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ int newValue = *value;
+ int n = DriverIndex(*value, map);
+ if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
+ if (n-- > 0)
+ newValue = map[n].driverValue;
+ }
+ else if (NORMALKEY(Key) == kRight) {
+ if (map[++n].userValue >= 0)
+ newValue = map[n].driverValue;
+ }
+ else
+ return state;
+ if (newValue != *value) {
+ *value = newValue;
+ Set();
+ }
+ state = osContinue;
+ }
+ return state;
+}
+
// --- cMenuEditChannel ------------------------------------------------------
class cMenuEditChannel : public cOsdMenu {
private:
cChannel *channel;
cChannel data;
+ void Setup(void);
public:
cMenuEditChannel(int Index);
virtual eOSState ProcessKey(eKeys Key);
@@ -408,24 +535,49 @@ cMenuEditChannel::cMenuEditChannel(int Index)
channel = Channels.Get(Index);
if (channel) {
data = *channel;
- Add(new cMenuEditStrItem( tr("Name"), data.name, sizeof(data.name), tr(FileNameChars)));
- Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency));
- Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv"));
- Add(new cMenuEditIntItem( tr("DiSEqC"), &data.diseqc, 0, 10)); //TODO exact limits???
- Add(new cMenuEditIntItem( tr("Srate"), &data.srate));
- Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0x1FFF));
- Add(new cMenuEditIntItem( tr("Apid1"), &data.apid1, 0, 0x1FFF));
- Add(new cMenuEditIntItem( tr("Apid2"), &data.apid2, 0, 0x1FFF));
- 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 cMenuEditCaItem( tr("CA"), &data.ca, true));
- Add(new cMenuEditIntItem( tr("Pnr"), &data.pnr, 0));
+ Setup();
}
}
+void cMenuEditChannel::Setup(void)
+{
+ int current = Current();
+ char type = *cSource::ToString(data.source);
+#define ST(s) if (strchr(s, type))
+
+ Clear();
+
+ // Parameters for all types of sources:
+ Add(new cMenuEditStrItem( tr("Name"), data.name, sizeof(data.name), tr(FileNameChars)));
+ Add(new cMenuEditSrcItem( tr("Source"), &data.source));
+ Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency));
+ Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0x1FFF));
+ Add(new cMenuEditIntItem( tr("Apid1"), &data.apid1, 0, 0x1FFF));
+ Add(new cMenuEditIntItem( tr("Apid2"), &data.apid2, 0, 0x1FFF));
+ 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 cMenuEditCaItem( tr("CA"), &data.ca, true));
+ Add(new cMenuEditIntItem( tr("Sid"), &data.sid, 0));
+ // Parameters for specific types of sources:
+ ST(" S ") Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv"));
+ ST("CS ") Add(new cMenuEditIntItem( tr("Srate"), &data.srate));
+ ST("CST") Add(new cMenuEditMapItem( tr("Inversion"), &data.inversion, InversionValues, tr("off")));
+ ST("CST") Add(new cMenuEditMapItem( tr("CoderateH"), &data.coderateH, CoderateValues, tr("none")));
+ ST(" T") Add(new cMenuEditMapItem( tr("CoderateL"), &data.coderateL, CoderateValues, tr("none")));
+ ST("C T") Add(new cMenuEditMapItem( tr("Modulation"), &data.modulation, ModulationValues, "QPSK"));
+ ST(" T") Add(new cMenuEditMapItem( tr("Bandwidth"), &data.bandwidth, BandwidthValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Transmission"), &data.transmission, TransmissionValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Guard"), &data.guard, GuardValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Hierarchy"), &data.hierarchy, HierarchyValues, tr("none")));
+
+ SetCurrent(Get(current));
+ Display();
+}
+
eOSState cMenuEditChannel::ProcessKey(eKeys Key)
{
+ int oldSource = data.source;
eOSState state = cOsdMenu::ProcessKey(Key);
if (state == osUnknown) {
@@ -436,6 +588,8 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key)
state = osBack;
}
}
+ if (Key != kNone && (data.source & cSource::st_Mask) != (oldSource & cSource::st_Mask))
+ Setup();
return state;
}
@@ -455,7 +609,7 @@ cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel)
{
index = Index;
channel = Channel;
- if (channel->groupSep)
+ if (channel->GroupSep())
SetColor(clrCyan, clrBackground);
Set();
}
@@ -463,10 +617,10 @@ cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel)
void cMenuChannelItem::Set(void)
{
char *buffer = NULL;
- if (!channel->groupSep)
- asprintf(&buffer, "%d\t%s", channel->number, channel->name );
+ if (!channel->GroupSep())
+ asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
else
- asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->name);
+ asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->Name());
SetText(buffer, false);
}
@@ -530,7 +684,7 @@ eOSState cMenuChannels::New(void)
Channels.ReNumber();
Add(new cMenuChannelItem(channel->Index()/*XXX*/, channel), true);
Channels.Save();
- isyslog("channel %d added", channel->number);
+ isyslog("channel %d added", channel->Number());
return AddSubMenu(new cMenuEditChannel(Current()));
}
@@ -539,7 +693,7 @@ eOSState cMenuChannels::Del(void)
if (Count() > 0) {
int Index = Current();
cChannel *channel = Channels.Get(Index);
- int DeletedChannel = channel->number;
+ int DeletedChannel = channel->Number();
// Check if there is a timer using this channel:
for (cTimer *ti = Timers.First(); ti; ti = (cTimer *)ti->Next()) {
if (ti->channel == DeletedChannel) {
@@ -578,8 +732,8 @@ eOSState cMenuChannels::Del(void)
void cMenuChannels::Move(int From, int To)
{
- int FromNumber = Channels.Get(From)->number;
- int ToNumber = Channels.Get(To)->number;
+ int FromNumber = Channels.Get(From)->Number();
+ int ToNumber = Channels.Get(To)->Number();
// Move and renumber the channels:
Channels.Move(From, To);
Channels.ReNumber();
@@ -933,7 +1087,7 @@ cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch)
cChannel *channel = Channels.GetByServiceID(eventInfo->GetServiceID());
if (channel) {
char *buffer;
- asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->name, 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
+ asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
SetTitle(buffer, false);
free(buffer);
int Line = 2;
@@ -984,7 +1138,7 @@ cMenuWhatsOnItem::cMenuWhatsOnItem(const cEventInfo *EventInfo)
eventInfo = EventInfo;
char *buffer = NULL;
cChannel *channel = Channels.GetByNumber(eventInfo->GetChannelNumber());
- asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->name : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle());
+ asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->Name() : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle());
SetText(buffer, false);
}
@@ -1026,7 +1180,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha
if (pArray[num]) {
cChannel *channel = Channels.GetByServiceID(pArray[num]->GetServiceID());
if (channel) {
- pArray[num]->SetChannelNumber(channel->number);
+ pArray[num]->SetChannelNumber(channel->Number());
num++;
}
}
@@ -1149,7 +1303,7 @@ cMenuSchedule::cMenuSchedule(void)
otherChannel = 0;
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel) {
- cMenuWhatsOn::SetCurrentChannel(channel->number);
+ cMenuWhatsOn::SetCurrentChannel(channel->Number());
schedules = cSIProcessor::Schedules(mutexLock);
PrepareSchedule(channel);
SetHelp(tr("Record"), tr("Now"), tr("Next"));
@@ -1170,11 +1324,11 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
{
Clear();
char *buffer = NULL;
- asprintf(&buffer, tr("Schedule - %s"), Channel->name);
+ asprintf(&buffer, tr("Schedule - %s"), Channel->Name());
SetTitle(buffer);
free(buffer);
if (schedules) {
- const cSchedule *Schedule = Channel->pnr ? schedules->GetSchedule(Channel->pnr) : schedules->GetSchedule();
+ const cSchedule *Schedule = Channel->Sid() ? schedules->GetSchedule(Channel->Sid()) : schedules->GetSchedule();
int num = Schedule->NumEvents();
const cEventInfo **pArray = MALLOC(const cEventInfo *, num);
if (pArray) {
@@ -1238,7 +1392,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
if (Count()) {
cChannel *channel = Channels.GetByServiceID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetServiceID());
if (channel)
- ChannelNr = channel->number;
+ ChannelNr = channel->Number();
}
now = true;
return AddSubMenu(new cMenuWhatsOn(schedules, true, ChannelNr));
@@ -1266,8 +1420,8 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
cChannel *channel = Channels.GetByServiceID(ei->GetServiceID());
if (channel) {
PrepareSchedule(channel);
- if (channel->number != cDevice::CurrentChannel()) {
- otherChannel = channel->number;
+ if (channel->Number() != cDevice::CurrentChannel()) {
+ otherChannel = channel->Number();
SetHelp(tr("Record"), tr("Now"), tr("Next"), tr("Switch"));
}
Display();
@@ -1451,7 +1605,7 @@ eOSState cMenuRecordings::Rewind(void)
return osContinue;
}
-eOSState cMenuRecordings::Del(void)
+eOSState cMenuRecordings::Delete(void)
{
cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
if (ri && !ri->IsDirectory()) {
@@ -1510,7 +1664,7 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
case kOk:
case kRed: return Play();
case kGreen: return Rewind();
- case kYellow: return Del();
+ case kYellow: return Delete();
case kBlue: return Summary();
default: break;
}
@@ -1636,17 +1790,44 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
// --- cMenuSetupLNB ---------------------------------------------------------
class cMenuSetupLNB : public cMenuSetupBase {
+private:
+ void Setup(void);
public:
cMenuSetupLNB(void);
+ virtual eOSState ProcessKey(eKeys Key);
};
cMenuSetupLNB::cMenuSetupLNB(void)
{
SetSection(tr("LNB"));
- Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF));
- Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"), &data.LnbFrequLo));
- Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi));
+ Setup();
+}
+
+void cMenuSetupLNB::Setup(void)
+{
+ int current = Current();
+
+ Clear();
+
Add(new cMenuEditBoolItem(tr("Setup.LNB$Use DiSEqC"), &data.DiSEqC));
+ if (!data.DiSEqC) {
+ Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF));
+ Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"), &data.LnbFrequLo));
+ Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi));
+ }
+
+ SetCurrent(Get(current));
+ Display();
+}
+
+eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
+{
+ int oldDiSEqC = data.DiSEqC;
+ eOSState state = cMenuSetupBase::ProcessKey(Key);
+
+ if (Key != kNone && data.DiSEqC != oldDiSEqC)
+ Setup();
+ return state;
}
// --- cMenuSetupCICAM -------------------------------------------------------
@@ -2092,7 +2273,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
}
break;
case kBlue: if (!HasSubMenu())
- state = replaying ? osStopReplay : osReplay;
+ state = replaying ? osStopReplay : cReplayControl::LastReplayed() ? osReplay : osContinue;
break;
default: break;
}
@@ -2152,10 +2333,10 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel)
{
int BufSize = Width() + 1;
char buffer[BufSize];
- if (Channel && Channel->number > 0)
- snprintf(buffer, BufSize, "%d%s %s", Channel->number, number ? "-" : "", Channel->name);
+ if (Channel && Channel->Number() > 0)
+ snprintf(buffer, BufSize, "%d%s %s", Channel->Number(), number ? "-" : "", Channel->Name());
else
- snprintf(buffer, BufSize, "%s", Channel ? Channel->name : tr("*** Invalid Channel ***"));
+ snprintf(buffer, BufSize, "%s", Channel ? Channel->Name() : tr("*** Invalid Channel ***"));
Interface->Fill(0, 0, Setup.OSDwidth, 1, clrBackground);
Interface->Write(0, 0, buffer);
const char *date = DayDateTime();
@@ -2266,7 +2447,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
if (channel) {
Interface->Clear();
DisplayChannel(channel);
- if (!channel->groupSep)
+ if (!channel->GroupSep())
group = -1;
}
}
@@ -2283,7 +2464,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
//XXX case kGreen: return osEventNow;
//XXX case kYellow: return osEventNext;
case kOk: if (group >= 0)
- Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(group))->number);
+ Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(group))->Number());
return osEnd;
default: if (NORMALKEY(Key) == kUp || NORMALKEY(Key) == kDown || (Key & (k_Repeat | k_Release)) == 0) {
cRemote::Put(Key);
@@ -2433,7 +2614,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer)
fileName = strdup(Recording.FileName());
cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName);
cChannel *ch = Channels.GetByNumber(timer->channel);
- recorder = new cRecorder(fileName, ch->ca, timer->priority, ch->vpid, ch->apid1, ch->apid2, ch->dpid1, ch->dpid2);
+ recorder = new cRecorder(fileName, ch->Ca(), timer->priority, ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2());
if (device->AttachReceiver(recorder)) {
Recording.WriteSummary();
cStatus::MsgRecording(device, Recording.Name());
@@ -2460,7 +2641,7 @@ bool cRecordControl::GetEventInfo(void)
cMutexLock MutexLock;
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
if (Schedules) {
- const cSchedule *Schedule = Schedules->GetSchedule(channel->pnr);
+ const cSchedule *Schedule = Schedules->GetSchedule(channel->Sid());
if (Schedule) {
eventInfo = Schedule->GetEventAround(Time);
if (eventInfo) {
diff --git a/menu.h b/menu.h
index 247057b..325a29f 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.h 1.46 2002/09/29 08:16:31 kls Exp $
+ * $Id: menu.h 1.47 2002/10/06 10:35:49 kls Exp $
*/
#ifndef __MENU_H
@@ -68,7 +68,7 @@ private:
bool Open(bool OpenSubMenus = false);
eOSState Play(void);
eOSState Rewind(void);
- eOSState Del(void);
+ eOSState Delete(void);
eOSState Summary(void);
public:
cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false);
diff --git a/params.txt b/params.txt
new file mode 100644
index 0000000..480a1a6
--- /dev/null
+++ b/params.txt
@@ -0,0 +1,4 @@
+Are the parameter names well chosen?
+
+ "Coderate" <--> FEC
+
diff --git a/recording.c b/recording.c
index c923446..544bbbd 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.c 1.67 2002/08/24 14:09:49 kls Exp $
+ * $Id: recording.c 1.68 2002/10/05 13:44:56 kls Exp $
*/
#include "recording.h"
@@ -14,6 +14,7 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "channels.h"
#include "i18n.h"
#include "interface.h"
#include "remux.h" //XXX+ I_FRAME
diff --git a/sources.c b/sources.c
new file mode 100644
index 0000000..fc660a5
--- /dev/null
+++ b/sources.c
@@ -0,0 +1,104 @@
+/*
+ * sources.c: Source handling
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: sources.c 1.1 2002/10/06 09:27:10 kls Exp $
+ */
+
+#include "sources.h"
+#include <ctype.h>
+
+// -- cSource ----------------------------------------------------------------
+
+cSource::cSource(void)
+{
+ code = stNone;
+ description = NULL;
+}
+
+cSource::~cSource()
+{
+ free(description);
+}
+
+bool cSource::Parse(const char *s)
+{
+ char *codeBuf = NULL;
+ if (2 == sscanf(s, "%a[^ ] %a[^\n]", &codeBuf, &description))
+ code = FromString(codeBuf);
+ free(codeBuf);
+ return code != stNone && description && *description;
+}
+
+const char *cSource::ToString(int Code)
+{
+ static char buffer[16];
+ char *q = buffer;
+ switch (Code & st_Mask) {
+ case stCable: *q++ = 'C'; break;
+ case stSat: *q++ = 'S';
+ {
+ int pos = Code & ~st_Mask;
+ q += snprintf(q, sizeof(buffer) - 2, "%u.%u", (pos & ~st_Neg) / 10, (pos & ~st_Neg) % 10); // can't simply use "%g" here since the silly 'locale' messes up the decimal point
+ *q++ = (Code & st_Neg) ? 'E' : 'W';
+ }
+ break;
+ case stTerr: *q++ = 'T'; break;
+ default: *q++ = Code + '0'; // backward compatibility
+ }
+ *q = 0;
+ return buffer;
+}
+
+int cSource::FromString(const char *s)
+{
+ int type = stNone;
+ switch (toupper(*s)) {
+ case 'C': type = stCable; break;
+ case 'S': type = stSat; break;
+ case 'T': type = stTerr; break;
+ case '0' ... '9': type = *s - '0'; break; // backward compatibility
+ default: esyslog("ERROR: unknown source key '%c'", *s);
+ return stNone;
+ }
+ int code = type;
+ if (type == stSat) {
+ int pos = 0;
+ bool dot = false;
+ bool neg = false;
+ while (*++s) {
+ switch (toupper(*s)) {
+ case '0' ... '9': pos *= 10;
+ pos += *s - '0';
+ break;
+ case '.': dot = true;
+ break;
+ case 'E': neg = true; // fall through to 'W'
+ case 'W': if (!dot)
+ pos *= 10;
+ break;
+ default: esyslog("ERROR: unknown source character '%c'", *s);
+ return stNone;
+ }
+ }
+ if (neg)
+ pos |= st_Neg;
+ code |= pos;
+ }
+ return code;
+}
+
+// -- cSources ---------------------------------------------------------------
+
+cSources Sources;
+
+cSource *cSources::Get(int Code)
+{
+ for (cSource *p = First(); p; p = Next(p)) {
+ if (p->Code() == Code)
+ return p;
+ }
+ return NULL;
+}
diff --git a/sources.conf b/sources.conf
new file mode 100644
index 0000000..f30e52f
--- /dev/null
+++ b/sources.conf
@@ -0,0 +1,50 @@
+# Sources configuration for VDR
+#
+# Format:
+#
+# code description
+#
+# Please contact kls@cadsoft.de before assigning a new code
+# to a description, in order to keep them unique.
+
+# Satellites
+
+S5E Sirius 2/3
+S7E Eutelsat W3
+S10E Eutelsat W1R
+S13E Hotbird 1-5
+S16E Eutelsat W2
+S19.2E Astra 1
+S23.5E Astra 3
+S26E Arabsat 2A/3A
+S28.2E Astra 2
+S28.5E Eurobird
+S30.E Arabsat 30.5E
+S31.3 Türksat 1B
+S36E Eutelsat W4 / Sesat
+S42E Turksat 1C / Eurasiasat
+
+S1W Thor 2/3 / Intelsat 707
+S4W Amos 1
+S5W Telecom 2C
+S7W Nilesat 101/102
+S8W Atlantic bird 2 / Telecom 2D
+S11W Express 3A
+S14W Express 2
+S15W Telstar 12
+S18W Intelsat
+S21W NSS 803
+S27.W Intelsat 27.5W
+S30W Hispasat 1
+S31.5W Intelsat 31.5W
+S34.5W Intelsat 34.5W
+S37.5W Telstar 11
+S43W PAS
+
+# Cable
+
+C Cable
+
+# Terrestrial
+
+T Terrestrial
diff --git a/sources.h b/sources.h
new file mode 100644
index 0000000..65d1bd6
--- /dev/null
+++ b/sources.h
@@ -0,0 +1,45 @@
+/*
+ * sources.h: Source handling
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: sources.h 1.1 2002/10/04 14:25:03 kls Exp $
+ */
+
+#ifndef __SOURCES_H
+#define __SOURCES_H
+
+#include "config.h"
+
+class cSource : public cListObject {
+public:
+ enum eSourceType {
+ stNone = 0x0000,
+ stCable = 0x4000,
+ stSat = 0x8000,
+ stTerr = 0xC000,
+ st_Mask = 0xC000,
+ st_Neg = 0x0800,
+ };
+private:
+ int code;
+ char *description;
+public:
+ cSource(void);
+ ~cSource();
+ int Code(void) const { return code; }
+ const char *Description(void) const { return description; }
+ bool Parse(const char *s);
+ static const char *ToString(int Code);
+ static int FromString(const char *s);
+ };
+
+class cSources : public cConfig<cSource> {
+public:
+ cSource *Get(int Code);
+ };
+
+extern cSources Sources;
+
+#endif //__SOURCES_H
diff --git a/svdrp.c b/svdrp.c
index 325b7da..81906b4 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.43 2002/09/28 15:50:19 kls Exp $
+ * $Id: svdrp.c 1.44 2002/10/05 13:45:05 kls Exp $
*/
#include "svdrp.h"
@@ -26,6 +26,7 @@
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
+#include "channels.h"
#include "config.h"
#include "device.h"
#include "keys.h"
@@ -412,7 +413,7 @@ void cSVDRP::CmdCHAN(const char *Option)
int i = 1;
cChannel *channel;
while ((channel = Channels.GetByNumber(i)) != NULL) {
- if (strcasecmp(channel->name, Option) == 0) {
+ if (strcasecmp(channel->Name(), Option) == 0) {
n = i;
break;
}
@@ -427,7 +428,7 @@ void cSVDRP::CmdCHAN(const char *Option)
cChannel *channel = Channels.GetByNumber(n);
if (channel) {
if (!cDevice::PrimaryDevice()->SwitchChannel(channel, true)) {
- Reply(554, "Error switching to channel \"%d\"", channel->number);
+ Reply(554, "Error switching to channel \"%d\"", channel->Number());
return;
}
}
@@ -441,7 +442,7 @@ void cSVDRP::CmdCHAN(const char *Option)
}
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (channel)
- Reply(250, "%d %s", channel->number, channel->name);
+ Reply(250, "%d %s", channel->Number(), channel->Name());
else
Reply(550, "Unable to find channel \"%d\"", cDevice::CurrentChannel());
}
@@ -630,7 +631,7 @@ void cSVDRP::CmdLSTC(const char *Option)
if (isnumber(Option)) {
cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10));
if (channel)
- Reply(250, "%d %s", channel->number, channel->ToText());
+ Reply(250, "%d %s", channel->Number(), channel->ToText());
else
Reply(501, "Channel \"%s\" not defined", Option);
}
@@ -640,9 +641,9 @@ void cSVDRP::CmdLSTC(const char *Option)
while (i <= Channels.MaxNumber()) {
cChannel *channel = Channels.GetByNumber(i);
if (channel) {
- if (strcasestr(channel->name, Option)) {
+ if (strcasestr(channel->Name(), Option)) {
if (next)
- Reply(-250, "%d %s", next->number, next->ToText());
+ Reply(-250, "%d %s", next->Number(), next->ToText());
next = channel;
}
}
@@ -653,7 +654,7 @@ void cSVDRP::CmdLSTC(const char *Option)
i++;
}
if (next)
- Reply(250, "%d %s", next->number, next->ToText());
+ Reply(250, "%d %s", next->Number(), next->ToText());
else
Reply(501, "Channel \"%s\" not defined", Option);
}
@@ -662,7 +663,7 @@ void cSVDRP::CmdLSTC(const char *Option)
for (int i = 1; i <= Channels.MaxNumber(); i++) {
cChannel *channel = Channels.GetByNumber(i);
if (channel)
- Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->number, channel->ToText());
+ Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), channel->ToText());
else
Reply(501, "Channel \"%d\" not found", i);
}
@@ -778,8 +779,8 @@ void cSVDRP::CmdMODC(const char *Option)
}
*channel = c;
Channels.Save();
- isyslog("channel %d modified", channel->number);
- Reply(250, "%d %s", channel->number, channel->ToText());
+ isyslog("channel %d modified", channel->Number());
+ Reply(250, "%d %s", channel->Number(), channel->ToText());
}
else
Reply(501, "Channel \"%d\" not defined", n);
@@ -844,8 +845,8 @@ void cSVDRP::CmdNEWC(const char *Option)
Channels.Add(channel);
Channels.ReNumber();
Channels.Save();
- isyslog("channel %d added", channel->number);
- Reply(250, "%d %s", channel->number, channel->ToText());
+ isyslog("channel %d added", channel->Number());
+ Reply(250, "%d %s", channel->Number(), channel->ToText());
}
else
Reply(501, "Error in channel settings");
diff --git a/vdr.5 b/vdr.5
index 00c58ed..8d6acfb 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 1.5 2002/09/29 13:06:40 kls Exp $
+.\" $Id: vdr.5 1.6 2002/10/06 08:56:01 kls Exp $
.\"
.TH vdr 5 "7 Sep 2002" "1.2.0" "Video Disk Recorder Files"
.SH NAME
@@ -29,7 +29,7 @@ character, followed by arbitrary text. Example:
A \fBchannel definition\fR is a line with channel data, where the fields
are separated by ':' characters. Example:
-\fBRTL:12188:h:1:27500:163:104:105:0:12003\fR
+\fBRTL:12188:h:S19.2E:27500:163:104:105:0:12003\fR
The line number of a channel definition (not counting group separators!)
defines the channel's number in OSD menus and the \fItimers.conf\fR file.
@@ -44,16 +44,44 @@ it has to be replaced by '|').
.B Frequency
The transponder frequency in MHz for DVB-S and DVB-C, kHz for DVB-T (as an integer).
.TP
-.B Polarization
-The polarization of the satellite signal. 'h' or 'H' for horizontal, 'v' or 'V'
-for vertical (DVB-S only).
+.B Parameters
+Various parameters, depending on whether this is a DVB-S, DVB-C or DVB-T channel.
+Each parameter consist of a key character, followed by an integer number that
+represents the actual setting of that parameter. The valid key characters, their
+meaning (and allowed values) are
+.TS
+tab (@);
+l l.
+\fBB\fR@Bandwidth (6, 7, 8)
+\fBC\fR@Code rate high priority (0, 12, 23, 34, 45, 56, 67, 78, 89)
+\fBD\fR@Code rate low priority (0, 12, 23, 34, 45, 56, 67, 78, 89)
+\fBG\fR@Guard interval (4, 8, 16, 32)
+\fBH\fR@Horizontal polarization
+\fBI\fR@Inversion (0, 1)
+\fBM\fR@Modulation (0, 16, 32, 64, 128, 256)
+\fBT\fR@Transmission mode (2, 8)
+\fBV\fR@Vertical polarization
+\fBY\fR@Hierarchy (0, 1, 2, 4)
+.TE
+The polarization parameters have no integer numbers following them. This is for
+compatibility with files from older versions and also to keep the DVB-S entries
+as simple as possible.
+
+The special value \fB999\fR is used for "automatic", which means the driver
+will automatically determine the proper value (if possible).
+
+An example of a parameter field for a DVB-T channel might look like this:
+
+\fBB8C23D12M64T2G32Y0\fR
.TP
-.B
-DiSEqC
-The DiSEqC code to use for this channel (integer, DVB-S only).
+.B Source
+The signal source of this channel, as defined in the file \fIsources.conf\fR.
+For compatibility with files from older versions numeric values will be accepted
+and also written back correctly, but they will have no meaning for the \fBDiSEqC\fR
+settings. You should replace the numerical values with the proper source identifiers
+defined in \fIsources.conf\fR.
.TP
-.B
-Srate
+.B Srate
The symbol rate of this channel (DVB-S and DVB-C only).
.TP
.B VPID
@@ -78,8 +106,8 @@ l l.
\fB>=100\fR@requires a specific decryption method defined in \fIca.conf\fR
.TE
.TP
-.B PNR
-The program number (aka service ID) of this channel.
+.B SID
+The service ID of this channel.
.SS TIMERS
The file \fItimers.conf\fR contains the timer setup.
Each line contains one timer definition, with individual fields
@@ -191,6 +219,69 @@ Arbitrary text that describes the recording made by this timer.
Any newline characters in the summary have to be replaced by '|', and
the summary may contain ':' characters. If this field is not empty, its
contents will be written into the \fIsummary.vdr\fR file of the recording.
+.SS SOURCES
+The file \fIsources.conf\fR defines the codes to be used in the \fBSource\fR field
+of channels in \fIchannels.conf\fR and assigns descriptive texts to them.
+Example:
+
+\fBS19.2E Astra 1\fR
+
+Anything after (and including) a '#' character is comment.
+
+The first character of the \fBcode\fR must be one of
+.TS
+tab (@);
+l l.
+\fBS\fR@Satellite
+\fBC\fR@Cable
+\fBT\fR@Terrestrial
+.TE
+and is followed by further data pertaining to that particular source. In case of
+\fBS\fRatellite this is the orbital position in degrees, followed by \fBE\fR for
+east or \fBW\fR for west.
+.SS DISEQC
+The file \fIdiseqc.conf\fR defines the \fBDiSEqC\fR control sequences to be sent
+to the DVB-S card in order to access a given satellite position and/or band.
+Example:
+
+\fBS19.2E 11700 V 9750 t v W15 [E0 10 38 F0] W15 A W15 t\fR
+
+Anything after (and including) a '#' character is comment.
+
+The first word in a parameter line must be one of the codes defined in the
+file \fIsources.conf\fR and tells which satellite this line applies to.
+
+Following is the "switch frequency" of the LNB (slof), which is the transponder
+frequency up to which this entry shall be used; the first entry with an slof greater
+than the actual transponder frequency will be used. Typically there is only one slof
+per LNB, but the syntax allows any number of frequency ranges to be defined.
+Note that there should be a last entry with the value \fB99999\fR for each satellite,
+which covers the upper frequency range.
+
+The third parameter defines the polarization to which this entry applies. It can
+be either \fBH\fR for horizontal or \fBV\fR for vertical.
+
+The fourth parameter specifies the "local oscillator frequency" (lof) of the LNB
+to use for the given frequency range. This number will be subtracted from the
+actual transponder frequency when tuning to the channel.
+
+The rest of the line holds the actual sequence of DiSEqC actions to be taken.
+The code letters used here are
+.TS
+tab (@);
+l l.
+\fBt\fR@22kHz tone off
+\fBT\fR@22kHz tone on
+\fBv\fR@voltage low (13V)
+\fBV\fR@voltage high (18V)
+\fBA\fR@mini A
+\fBB\fR@mini B
+\fBWnn\fR@wait nn milliseconds (nn may be any positive integer number)
+\fB[xx ...]\fR@hex code sequence (max. 6)
+.TE
+There can be any number of actions in a line, including none at all - in which case
+the entry would be used only to set the LOF to use for the given frequency range
+and polarization.
.SS CONDITIONAL ACCESS
The file \fIca.conf\fR defines the numbers to be used in the \fBConditional access\fR
field of channels in \fIchannels.conf\fR and assigns descriptive texts to them.
diff --git a/vdr.c b/vdr.c
index fd23ae1..7e22477 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.124 2002/09/29 12:55:03 kls Exp $
+ * $Id: vdr.c 1.125 2002/10/06 10:25:04 kls Exp $
*/
#include <getopt.h>
@@ -30,9 +30,11 @@
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
+#include "channels.h"
#include "config.h"
#include "cutter.h"
#include "device.h"
+#include "diseqc.h"
#include "dvbdevice.h"
#include "eitscan.h"
#include "i18n.h"
@@ -44,6 +46,7 @@
#include "plugin.h"
#include "rcu.h"
#include "recording.h"
+#include "sources.h"
#include "tools.h"
#include "videodir.h"
@@ -311,9 +314,11 @@ int main(int argc, char *argv[])
cPlugin::SetConfigDirectory(ConfigDirectory);
Setup.Load(AddDirectory(ConfigDirectory, "setup.conf"));
+ Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true);
+ Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true);
Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"));
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf"));
- Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"));
+ Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true);
SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true);
CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true);
Keys.Load(AddDirectory(ConfigDirectory, "remote.conf"));