[ANNOUNCE] vdr-rotor support patches for VDR-1.5.16

Message ID 47DC1145.9030203@iki.fi
State New
Headers

Commit Message

Seppo Ingalsuo March 15, 2008, 6:11 p.m. UTC
  Hello,

I didn't get rotor plugin to work possibly due to a tone on hazard 
situation compared to idle time requirements around DiSEqC message. Here 
is patch for multiproto/H.264 patched vdr-1.5.16 that integrates a 
subset of rotor plugin functions (using rotor plugin source code ;^) 
into vdr's LNB setup menu and DiSEqC system. It adds G command into 
diseqc.conf or automatically sends gotox, if gotox enabled in setup, 
when diseq.conf is not used before tuning. Rotor plugin is not needed.  
This seems to work for me.

Cheers,
Seppo
# 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
#   G         GotoX, includes tV W15, Gotox, W15, <2nd Gotox>, dish move wait
#   Wnn       wait nn milliseconds (nn may be any positive integer number)
#   [xx ...]  hex code sequence (max. 6)
#
# The 'command...' part is optional.
#

S7.0W 11700 V  9750 G v t
S7.0W 99999 V 10600 G v T
S7.0W 11700 H  9750 G V t
S7.0W 99999 H 10600 G V T

S5.0W 11700 V  9750 G v t
S5.0W 99999 V 10600 G v T
S5.0W 11700 H  9750 G V t
S5.0W 99999 H 10600 G V T

S1.0W 11700 V  9750 G v t
S1.0W 99999 V 10600 G v T
S1.0W 11700 H  9750 G V t
S1.0W 99999 H 10600 G V T

S5.0E 11700 V  9750 G v t 
S5.0E 99999 V 10600 G v T
S5.0E 11700 H  9750 G V t
S5.0E 99999 H 10600 G V T

S7.0E 11700 V  9750 G v t 
S7.0E 99999 V 10600 G v T
S7.0E 11700 H  9750 G V t
S7.0E 99999 H 10600 G V T

S10.0E 11700 V  9750 G v t 
S10.0E 99999 V 10600 G v T
S10.0E 11700 H  9750 G V t
S10.0E 99999 H 10600 G V T

S13.0E 11700 V  9750 G v t
S13.0E 99999 V 10600 G v T
S13.0E 11700 H  9750 G V t
S13.0E 99999 H 10600 G V T

S16.0E 11700 V  9750 G v t
S16.0E 99999 V 10600 G v T
S16.0E 11700 H  9750 G V t
S16.0E 99999 H 10600 G V T

S19.2E 11700 V  9750 G v t
S19.2E 99999 V 10600 G v T
S19.2E 11700 H  9750 G V t
S19.2E 99999 H 10600 G V T

S21.5E 11700 V  9750 G v t
S21.5E 99999 V 10600 G v T
S21.5E 11700 H  9750 G V t
S21.5E 99999 H 10600 G V T

S23.5E 11700 V  9750 G v t
S23.5E 99999 V 10600 G v T
S23.5E 11700 H  9750 G V t
S23.5E 99999 H 10600 G V T

S26.0E 11700 V  9750 G v t
S26.0E 99999 V 10600 G v T
S26.0E 11700 H  9750 G V t
S26.0E 99999 H 10600 G V T

S28.2E 11700 V  9750 G v t
S28.2E 99999 V 10600 G v T
S28.2E 11700 H  9750 G V t
S28.2E 99999 H 10600 G V T

S28.5E 11700 V  9750 G v t
S28.5E 99999 V 10600 G v T
S28.5E 11700 H  9750 G V t
S28.5E 99999 H 10600 G V T

S30.5E 11700 V  9750 G v t
S30.5E 99999 V 10600 G v T
S30.5E 11700 H  9750 G V t
S30.5E 99999 H 10600 G V T

S31.3E 11700 V  9750 G v t
S31.3E 99999 V 10600 G v T
S31.3E 11700 H  9750 G V t
S31.3E 99999 H 10600 G V T

S36.0E 11700 V  9750 G v t
S36.0E 99999 V 10600 G v T
S36.0E 11700 H  9750 G V t
S36.0E 99999 H 10600 G V T

S39.0E 11700 V  9750 G v t
S39.0E 99999 V 10600 G v T
S39.0E 11700 H  9750 G V t
S39.0E 99999 H 10600 G V T

S40.0E 11700 V  9750 G v t
S40.0E 99999 V 10600 G v T
S40.0E 11700 H  9750 G V t
S40.0E 99999 H 10600 G V T

S42.0E 11700 V  9750 G v t
S42.0E 99999 V 10600 G v T
S42.0E 11700 H  9750 G V t
S42.0E 99999 H 10600 G V T

S45.0E 11700 V  9750 G v t
S45.0E 99999 V 10600 G v T
S45.0E 11700 H  9750 G V t
S45.0E 99999 H 10600 G V T

S47.0E 11700 V  9750 G v t
S47.0E 99999 V 10600 G v T
S47.0E 11700 H  9750 G V t
S47.0E 99999 H 10600 G V T

S48.0E 11700 V  9750 G v t
S48.0E 99999 V 10600 G v T
S48.0E 11700 H  9750 G V t
S48.0E 99999 H 10600 G V T

S50.0E 11700 V  9750 G v t
S50.0E 99999 V 10600 G v T
S50.0E 11700 H  9750 G V t
S50.0E 99999 H 10600 G V T

S53.0E 11700 V  9750 G v t
S53.0E 99999 V 10600 G v T
S53.0E 11700 H  9750 G V t
S53.0E 99999 H 10600 G V T

# Examples:
#
# Full DiSEqC sequence:
#
#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
#
#S21.5E  11700 V  9750  t v W15 [E0 10 38 F4] W15 B W15 t
#S21.5E  99999 V 10600  t v W15 [E0 10 38 F5] W15 B W15 T
#S21.5E  11700 H  9750  t V W15 [E0 10 38 F6] W15 B W15 t
#S21.5E  99999 H 10600  t V W15 [E0 10 38 F7] W15 B W15 T
#
# Optimized for mini DiSEqC (aka toneburst):
#
# S19.2E  11700 V  9750  t v W15 A W15 t
# S19.2E  99999 V 10600  t v W15 A W15 T
# S19.2E  11700 H  9750  t V W15 A W15 t
# S19.2E  99999 H 10600  t V W15 A W15 T
#
# S21.5E  11700 V  9750  t v W15 B W15 t
# S21.5E  99999 V 10600  t v W15 B W15 T
# S21.5E  11700 H  9750  t V W15 B W15 t
# S21.5E  99999 H 10600  t V W15 B W15 T
#
# Optimized for full DiSEqC:
#
# S19.2E  11700 V  9750  [E0 10 38 F0]
# S19.2E  99999 V 10600  [E0 10 38 F1]
# S19.2E  11700 H  9750  [E0 10 38 F2]
# S19.2E  99999 H 10600  [E0 10 38 F3]
#
# S21.5E  11700 V  9750  [E0 10 38 F4]
# S21.5E  99999 V 10600  [E0 10 38 F5]
# S21.5E  11700 H  9750  [E0 10 38 F6]
# S21.5E  99999 H 10600  [E0 10 38 F7]
  

Patch

--- vdr-1.5.16-orig/config.h	2008-02-17 18:04:52.000000000 +0200
+++ vdr-1.5.16-gx/config.h	2008-03-13 21:53:42.000000000 +0200
@@ -215,6 +215,14 @@ 
   int LnbFrequLo;
   int LnbFrequHi;
   int DiSEqC;
+  int GotoxRepeat;
+  int GotoxSN;
+  int GotoxEW;
+  int GotoxSpeed;
+  int GotoxLat;
+  int GotoxLong;
+  int UseGotox;
+  int GotoxPrevSource;
   int SetSystemTime;
   int TimeSource;
   int TimeTransponder;
--- vdr-1.5.16-orig/config.c	2008-02-17 15:39:00.000000000 +0200
+++ vdr-1.5.16-gx/config.c	2008-03-15 18:04:44.000000000 +0200
@@ -229,6 +229,11 @@ 
   LnbFrequLo =  9750;
   LnbFrequHi = 10600;
   DiSEqC = 0;
+  UseGotox = 0;
+  GotoxSpeed = 100;
+  GotoxRepeat = 0;
+  GotoxSN = 0; GotoxLat = 613; GotoxEW = 1; GotoxLong = 236; // Somewhere at Tampere, Finland :^)
+  GotoxPrevSource = 0;
   SetSystemTime = 0;
   TimeSource = 0;
   TimeTransponder = 0;
@@ -402,6 +407,14 @@ 
   else if (!strcasecmp(Name, "LnbFrequLo"))          LnbFrequLo         = atoi(Value);
   else if (!strcasecmp(Name, "LnbFrequHi"))          LnbFrequHi         = atoi(Value);
   else if (!strcasecmp(Name, "DiSEqC"))              DiSEqC             = atoi(Value);
+  else if (!strcasecmp(Name, "UseGotox"))            UseGotox           = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxSpeed"))          GotoxSpeed         = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxRepeat"))         GotoxRepeat        = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxSN"))             GotoxSN            = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxLat"))            GotoxLat           = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxEW"))             GotoxEW            = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxLong"))           GotoxLong          = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxPrevSource"))     GotoxPrevSource    = atoi(Value);
   else if (!strcasecmp(Name, "SetSystemTime"))       SetSystemTime      = atoi(Value);
   else if (!strcasecmp(Name, "TimeSource"))          TimeSource         = cSource::FromString(Value);
   else if (!strcasecmp(Name, "TimeTransponder"))     TimeTransponder    = atoi(Value);
@@ -485,6 +498,14 @@ 
   Store("LnbFrequLo",         LnbFrequLo);
   Store("LnbFrequHi",         LnbFrequHi);
   Store("DiSEqC",             DiSEqC);
+  Store("UseGotox",           UseGotox);
+  Store("GotoxSpeed",         GotoxSpeed);
+  Store("GotoxRepeat",        GotoxRepeat);
+  Store("GotoxSN",            GotoxSN);
+  Store("GotoxLat",           GotoxLat);
+  Store("GotoxEW",            GotoxEW);
+  Store("GotoxLong",          GotoxLong);
+  Store("GotoxPrevSource",    GotoxPrevSource);
   Store("SetSystemTime",      SetSystemTime);
   Store("TimeSource",         cSource::ToString(TimeSource));
   Store("TimeTransponder",    TimeTransponder);
--- vdr-1.5.16-orig/dvbdevice.c	2008-02-29 00:00:54.000000000 +0200
+++ vdr-1.5.16-gx/dvbdevice.c	2008-03-15 19:16:23.000000000 +0200
@@ -17,6 +17,7 @@ 
 #include <linux/dvb/video.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <math.h>
 #include "channels.h"
 #include "diseqc.h"
 #include "dvbci.h"
@@ -205,9 +206,91 @@ 
   return f;
 }
 
+void HandleGotox(int fd_frontend, int new_source)
+{
+  
+  int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
+  int satlong;
+  int satprev;
+  float waitseconds = 0;
+
+  if (Setup.UseGotox == 0)
+    return;
+
+  // Check if zapped into new source position?
+  if (new_source != Setup.GotoxPrevSource) {
+    satlong = (new_source & ~0xC800);
+    satprev = (Setup.GotoxPrevSource & ~0xC800);
+    if ((new_source & 0xC000) != 0x8000) 
+      return; // Fail
+    if (new_source & 0x0800)
+      satlong = satlong * (-1);
+    if (Setup.GotoxPrevSource & 0x0800)
+      satprev = satprev * (-1);
+    if (Setup.GotoxSpeed > 0) {
+      waitseconds = fabs(satlong-satprev)/(float)(Setup.GotoxSpeed);
+      if (waitseconds < 0.0) waitseconds = 0.0; // Should not happen but ...
+      if (waitseconds > 60.0) waitseconds = 60.0; // Limit wait time to 60s
+    }
+    int Long=Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong;
+    int Lat=Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat;
+    double azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800));
+    double x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800));
+    double elevation=atan((cos(x)-0.1513)/sin(x));
+    double SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800)
+			   -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI;
+    int tmp=(int)(fabs(180-SatHourangle)*10);
+    tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+    int p2=(tmp%0x0100);
+    int p1=(tmp/0x0100);
+    if (SatHourangle < 180)
+      p1 |= 0xe0;
+    else
+      p1 |= 0xd0;
+
+    dsyslog("DiSEqC GotoX %d (%d) -> %d (%d), wait time %4.1fs",
+	    satprev, Setup.GotoxPrevSource, satlong, new_source, waitseconds);
+
+#if 1
+    // Set high LNB voltage and tone off, then wait > 15ms
+    CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18));
+    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
+    usleep(20000);
+    
+    // Send 1st GotoX command, then wait > 15ms
+    uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2};
+    struct dvb_diseqc_master_cmd gotox_cmd;
+    memcpy(gotox_cmd.msg, gotox_bytes, 5);
+    gotox_cmd.msg_len = 5;
+    CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+    usleep(20000);
+
+    // Send repeated GotoX command, then wait > 15ms
+    if (Setup.GotoxRepeat) {
+      gotox_bytes[0] = 0xe1;
+      memcpy(gotox_cmd.msg, gotox_bytes, 5);
+      CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+      usleep(20000);
+    }
+    
+    // Wait for dish movement
+    while (waitseconds > 0.0) {
+      usleep(100000); // 100ms
+      waitseconds = waitseconds - 100e-3;
+    }
+
+#endif
+
+    Setup.GotoxPrevSource = new_source;
+    dsyslog("DiSEqC GotoX done.");
+  }
+}
+
+
 bool cDvbTuner::SetFrontend(void)
 {
   dvbfe_params Frontend;
+
   memset(&Frontend, 0, sizeof(Frontend));
 
   if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) {
@@ -226,6 +309,7 @@ 
                     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::daGotoX:     HandleGotox(fd_frontend, channel.Source()); break;
                     case cDiseqc::daCodes: {
                          int n = 0;
                          uchar *codes = diseqc->Codes(n);
@@ -249,6 +333,10 @@ 
            }
         }
      else {
+        // Send GotoX DiSEqC command if activated in vdr setup. Then wait with high LNB voltage
+        // estimated time for dish movement
+        HandleGotox(fd_frontend, channel.Source()); 
+
         int tone = SEC_TONE_OFF;
         if (frequency < (unsigned int)Setup.LnbSLOF) {
            frequency -= Setup.LnbFrequLo;
--- vdr-1.5.16-orig/menu.c	2008-02-29 00:00:54.000000000 +0200
+++ vdr-1.5.16-gx/menu.c	2008-03-15 17:48:43.000000000 +0200
@@ -2542,8 +2542,14 @@ 
      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));
-     }
-
+  }
+  Add(new cMenuEditBoolItem(tr("Setup.LNB$Use GotoX dish positioning"), &data.UseGotox));
+  if (data.UseGotox) {
+     Add(new cMenuEditBoolItem(tr("Setup.LNB$Repeat GotoX commands"), &data.GotoxRepeat));
+     Add(new cMenuEditIntpItem(tr("Setup.LNB$Latitude"), &data.GotoxLat,0,900,&data.GotoxSN,tr("North"),tr("South")));
+     Add(new cMenuEditIntpItem(tr("Setup.LNB$Longitude"), &data.GotoxLong,0,1800,&data.GotoxEW,tr("West"),tr("East")));
+     Add(new cMenuEditIntdItem(tr("Setup.LNB$Rotor speed (deg/s)"), &data.GotoxSpeed, 1, 100));
+  }
   SetCurrent(Get(current));
   Display();
 }
@@ -2551,10 +2557,15 @@ 
 eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
 {
   int oldDiSEqC = data.DiSEqC;
+  int oldUseGotox = data.UseGotox;
   eOSState state = cMenuSetupBase::ProcessKey(Key);
 
   if (Key != kNone && data.DiSEqC != oldDiSEqC)
      Setup();
+
+  if (Key != kNone && data.UseGotox != oldUseGotox)
+     Setup();
+
   return state;
 }
 
--- vdr-1.5.16-orig/menuitems.c	2008-02-29 00:00:54.000000000 +0200
+++ vdr-1.5.16-gx/menuitems.c	2008-03-15 17:52:01.000000000 +0200
@@ -1039,3 +1039,121 @@ 
   if (plugin)
      plugin->SetupStore(Name, Value);
 }
+
+// cMenuEditIntpItem & cMenuEditIntdItem for GotoX function
+
+void cMenuEditIntpItem::Set(void)
+{
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d.%d %s", *value/10, *value % 10, *value2 ? trueString : falseString);
+  SetValue(buf);
+}
+
+void cMenuEditIntdItem::Set(void)
+{
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d.%d", *value/10, *value % 10);
+  SetValue(buf);
+}
+
+
+cMenuEditIntpItem::cMenuEditIntpItem(const char *Name, int *Value, int Min, int Max,int *Value2, const char *FalseString,const char *TrueString):cMenuEditIntItem(Name, Value, Min, Max)
+{
+  value = Value;
+  value2= Value2;
+  trueString = TrueString;
+  falseString = FalseString;
+  min = Min;
+  max = Max;
+  Set();
+}
+
+cMenuEditIntdItem::cMenuEditIntdItem(const char *Name, int *Value, int Min, int Max):cMenuEditIntItem(Name, Value, Min, Max)
+{
+  value = Value;
+  min = Min;
+  max = Max;
+  Set();
+}
+
+eOSState cMenuEditIntpItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+  if (state == osUnknown)
+  {
+    int newValue = *value;
+    int newValue2= *value2;
+    Key = NORMALKEY(Key);
+    switch (Key) {
+      case kNone  : break;
+      case k0...k9:
+                    if (fresh)
+                    {
+                      *value = 0;
+                      fresh = false;
+                    }
+                    newValue = *value * 10 + (Key - k0);
+                    break;
+      case kLeft  :
+                    newValue2 = 0;
+                    fresh = true;
+                    break;
+      case kRight :
+                    newValue2 = 1;
+                    fresh = true;
+                    break;
+      default     :
+                    if (*value < min) { *value = min; Set(); }
+                    if (*value > max) { *value = max; Set(); }
+                    return state;
+                 }
+    if ((!fresh || min <= newValue) && newValue <= max)
+    {
+      *value = newValue;
+      *value2 = newValue2;
+      Set();
+    }
+ state = osContinue;
+  }
+  return state;
+}
+
+eOSState cMenuEditIntdItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+  if (state == osUnknown)
+  {
+    int newValue = *value;
+    Key = NORMALKEY(Key);
+    switch (Key) {
+      case kNone  : break;
+      case k0...k9:
+                    if (fresh)
+                    {
+                      *value = 0;
+                      fresh = false;
+                    }
+                    newValue = *value * 10 + (Key - k0);
+                    break;
+      case kLeft  :
+	            newValue = *value - 1;
+                    fresh = true;
+                    break;
+      case kRight :
+                    newValue = *value + 1;
+                    fresh = true;
+                    break;
+      default     :
+                    if (*value < min) { *value = min; Set(); }
+                    if (*value > max) { *value = max; Set(); }
+                    return state;
+                 }
+    if ((!fresh || min <= newValue) && newValue <= max)
+    {
+      *value = newValue;
+      Set();
+    }
+    state = osContinue;
+  }
+  return state;
+}
--- vdr-1.5.16-orig/menuitems.h	2008-02-29 00:00:54.000000000 +0200
+++ vdr-1.5.16-gx/menuitems.h	2008-03-15 17:49:18.000000000 +0200
@@ -187,4 +187,22 @@ 
   void SetPlugin(cPlugin *Plugin);
   };
 
+class cMenuEditIntpItem : public cMenuEditIntItem {
+protected:
+  virtual void Set(void);
+  const char *falseString, *trueString;
+  int *value2;
+public:
+  cMenuEditIntpItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX, int *Value2=0, const char *FalseString = "", const char *TrueSting = NULL);
+  virtual eOSState ProcessKey(eKeys Key);
+};
+
+class cMenuEditIntdItem : public cMenuEditIntItem {
+protected:
+  virtual void Set(void);
+public:
+  cMenuEditIntdItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX);
+  virtual eOSState ProcessKey(eKeys Key);
+};
+
 #endif //__MENUITEMS_H
--- vdr-1.5.16-orig/diseqc.c	2008-02-10 16:09:27.000000000 +0200
+++ vdr-1.5.16-gx/diseqc.c	2008-03-08 17:21:30.000000000 +0200
@@ -114,6 +114,7 @@ 
           case 'V': return daVoltage18;
           case 'A': return daMiniA;
           case 'B': return daMiniB;
+	  case 'G': return daGotoX;
           case 'W': *CurrentAction = Wait(*CurrentAction); break;
           case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone;
           default: return daNone;
--- vdr-1.5.16-orig/diseqc.h	2002-12-07 15:54:02.000000000 +0200
+++ vdr-1.5.16-gx/diseqc.h	2008-03-06 22:50:47.000000000 +0200
@@ -22,6 +22,7 @@ 
     daVoltage18,
     daMiniA,
     daMiniB,
+    daGotoX,
     daCodes,
     };
   enum { MaxDiseqcCodes = 6 };