--- /home/knap/Patch/vdr-2.0.3/dvbdevice.c	2013-09-01 23:04:05.000000000 +0200
+++ /home/knap/Patch/dvbdevice.c	2013-10-13 10:34:27.489228803 +0200
@@ -532,33 +532,110 @@
 //#define DEBUG_SIGNALSTRENGTH
 //#define DEBUG_SIGNALQUALITY
 
+// Inizio Modifica
+
+#define LOCK_THRESHOLD 5 // indicates that all 5 FE_HAS_* flags are set
+
 int cDvbTuner::GetSignalStrength(void) const
 {
-  ClearEventQueue();
-  uint16_t Signal;
-  while (1) {
-        if (ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
-           break;
-        if (errno != EINTR)
-           return -1;
+  fe_status_t Status;
+  if (GetFrontendStatus(Status)) {
+     // Actually one would expect these checks to be done from FE_HAS_SIGNAL to FE_HAS_LOCK, but some drivers (like the stb0899) are broken, so FE_HAS_LOCK is the only one that (hopefully) is generally reliable...
+     if ((Status & FE_HAS_LOCK) == 0) {
+        if ((Status & FE_HAS_SIGNAL) == 0)
+           return 0;
+        if ((Status & FE_HAS_CARRIER) == 0)
+           return 1;
+        if ((Status & FE_HAS_VITERBI) == 0)
+           return 2;
+        if ((Status & FE_HAS_SYNC) == 0)
+           return 3;
+        return 4;
         }
-  uint16_t MaxSignal = 0xFFFF; // Let's assume the default is using the entire range.
-  // Use the subsystemId to identify individual devices in case they need
-  // special treatment to map their Signal value into the range 0...0xFFFF.
-  switch (subsystemId) {
-    case 0x13C21019: // TT-budget S2-3200 (DVB-S/DVB-S2)
-    case 0x1AE40001: // TechniSat SkyStar HD2 (DVB-S/DVB-S2)
-                     MaxSignal = 670; break;
-    }
-  int s = int(Signal) * 100 / MaxSignal;
-  if (s > 100)
-     s = 100;
 #ifdef DEBUG_SIGNALSTRENGTH
-  fprintf(stderr, "FE %d/%d: %08X S = %04X %04X %3d%%\n", adapter, frontend, subsystemId, MaxSignal, Signal, s);
+     bool HasSignal = true;
+#endif
+     uint16_t Signal;
+     while (1) {
+          if (ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
+              break;
+           if (errno != EINTR) {
+              Signal = 0xFFFF;
+#ifdef DEBUG_SIGNALSTRENGTH
+              HasSignal = false;
+#endif
+              break;
+              }
+           }
+#ifdef DEBUG_SIGNALSTRENGTH
+     bool HasBer = true;
+#endif
+     uint32_t Ber;
+     while (1) {
+           if (ioctl(fd_frontend, FE_READ_BER, &Ber) != -1)
+              break;
+           if (errno != EINTR) {
+              Ber = 0;
+#ifdef DEBUG_SIGNALSTRENGTH
+              HasBer = false;
 #endif
-  return s;
+              break;
+              }
+           }
+#ifdef DEBUG_SIGNALSTRENGTH
+     bool HasUnc = true;
+#endif
+     uint32_t Unc;
+     while (1) {
+           if (ioctl(fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1)
+              break;
+           if (errno != EINTR) {
+              Unc = 0;
+#ifdef DEBUG_SIGNALSTRENGTH
+              HasUnc = false;
+#endif
+              break;
+              }
+           }
+     uint16_t MinSignal = 0x0000;
+     uint16_t MaxSignal = 0xFFFF; // Let's assume the default is using the entire range.
+     // Use the subsystemId to identify individual devices in case they need
+     // special treatment to map their Snr value into the range 0...0xFFFF.
+     switch (subsystemId) {
+       case 0x13C21019: // TT-budget S2-3200 (DVB-S/DVB-S2)
+       case 0x1AE40001: // TechniSat SkyStar HD2 (DVB-S/DVB-S2)
+                        if (frontendType == SYS_DVBS2) {
+                           MinSignal = 10;
+                           MaxSignal = 70;
+                           }
+                        else
+//                           MaxSignal = 200;
+                           MaxSignal = 670;
+
+                        break;
+       case 0x20130245: // PCTV Systems PCTV 73ESE
+       case 0x2013024F: // PCTV Systems nanoStick T2 290e
+//                        MaxSignal = 255; break;
+                            MaxSignal = 670;
+
+       }
+     int a = int(constrain(Signal, MinSignal, MaxSignal)) * 350 / (MaxSignal - MinSignal);
+     int b = 100 - (Unc * 10 + (Ber / 256) * 5);
+     if (b < 0)
+        b = 0;
+     int s = LOCK_THRESHOLD + a * b * (100 - LOCK_THRESHOLD) / 100 / 100;
+     if (s > 100)
+        s = 100;
+    #ifdef DEBUG_SIGNALSTRENGTH
+     fprintf(stderr, "FE %d/%d: %08X S = %04X %04X %d %5d %5d %3d%%\n", adapter, frontend, subsystemId, MaxSignal, Signal, HasSignal, HasBer ? int(Ber) : -1, HasUnc ? int(Unc) : -1, s);
+#endif
+     return s;
+     }
+  return -1;
 }
 
+// Fine Modifica
+
 #define LOCK_THRESHOLD 5 // indicates that all 5 FE_HAS_* flags are set
 
 int cDvbTuner::GetSignalQuality(void) const
