From c2ce6919b963da4bc45f843dcd598b6f997ff2d0 Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Date: Sun, 6 Oct 2019 08:42:36 -0300
Subject: [PATCH] Fix DVBv5 stats logic

If DVBv5 stats are available, use it for everything, instead
of trying the legacy API too.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c
index 25b35942855a..010faa82f59d 100644
--- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c
+++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c
@@ -879,7 +879,7 @@ linuxdvb_frontend_monitor ( void *aux )
   signal_status_t sigstat;
   streaming_message_t sm;
   service_t *s;
-  int logit = 0, retune, e;
+  int logit = 0, retune, e, i;
   uint32_t period = MINMAX(lfe->lfe_status_period, 250, 8000);
 #if DVB_VER_ATLEAST(5,10)
   struct dtv_property fe_properties[6];
@@ -1031,53 +1031,52 @@ linuxdvb_frontend_monitor ( void *aux )
 
   logit = tvhlog_limit(&lfe->lfe_status_log, 3600);
 
+  /* Check if DVBv5 stats are available */
+  gotprop = 0;
   if(ioctl_check(lfe, 0) && !lfe->lfe_old_status &&
      !ioctl(lfe->lfe_fe_fd, FE_GET_PROPERTY, &dtv_prop)) {
+
+     for (i = 0; i < dtv_prop.num; i++)
+       if (fe_properties[i].u.st.len)
+         break;
+     if (i < dtv_prop.num)
+       gotprop = 1;
+  }
+
+  if (gotprop) {
     /* Signal strength */
-    gotprop = 0;
     if(ioctl_check(lfe, 1) && fe_properties[0].u.st.len > 0) {
       if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_RELATIVE) {
         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
         mmi->tii_stats.signal = sig_multiply(fe_properties[0].u.st.stat[0].uvalue, lfe->lfe_sig_multiplier);
-        gotprop = 1;
       }
       else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_DECIBEL) {
         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_DECIBEL;
         mmi->tii_stats.signal = sig_multiply(fe_properties[0].u.st.stat[0].svalue, lfe->lfe_sig_multiplier);
-        gotprop = 1;
       }
       else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
         mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
-        gotprop = 1;
-      }
-      else {
-        ioctl_bad(lfe, 1);
-        mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
-        if (logit)
-          tvhwarn(LS_LINUXDVB, "Unhandled signal scale: %d",
-                  fe_properties[0].u.st.stat[0].scale);
       }
     }
-    if(!gotprop && ioctl_check(lfe, 2)) {
-      /* try old API */
-      if (!ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) {
-        mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE;
-        mmi->tii_stats.signal = sig_multiply(u16, lfe->lfe_sig_multiplier);
-      }
-      else {
-        ioctl_bad(lfe, 2);
-        mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
-        if (logit)
-          tvhwarn(LS_LINUXDVB, "Unable to provide signal strength value.");
-      }
+    else {
+      ioctl_bad(lfe, 1);
+      mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
+      if (logit)
+        tvhwarn(LS_LINUXDVB, "Unhandled signal scale: %d",
+                fe_properties[0].u.st.stat[0].scale);
+    }
+
+    if(ioctl_check(lfe, 2)) {
+      ioctl_bad(lfe, 2);
+      mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
+      if (logit)
+        tvhwarn(LS_LINUXDVB, "Unable to provide signal strength value.");
     }
 
     /* ERROR_BIT_COUNT */
-    gotprop = 0;
     if(ioctl_check(lfe, 3) && fe_properties[1].u.st.len > 0) {
       if(fe_properties[1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
         mmi->tii_stats.ec_bit = fe_properties[1].u.st.stat[0].uvalue;
-        gotprop = 1;
       }
       else {
         ioctl_bad(lfe, 3);
@@ -1087,11 +1086,9 @@ linuxdvb_frontend_monitor ( void *aux )
       }
     }
     /* TOTAL_BIT_COUNT */
-    if(gotprop && (fe_properties[2].u.st.len > 0)) {
-      gotprop = 0;
+    if(fe_properties[2].u.st.len > 0) {
       if(ioctl_check(lfe, 4) && fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) {
         mmi->tii_stats.tc_bit = fe_properties[2].u.st.stat[0].uvalue;
-        gotprop = 1;
       }
       else {
         ioctl_bad(lfe, 4);
@@ -1101,33 +1098,19 @@ linuxdvb_frontend_monitor ( void *aux )
                   fe_properties[2].u.st.stat[0].scale);
       }
     }
-    if(!gotprop && ioctl_check(lfe, 5)) {
-      /* try old API */
-      if (!ioctl(lfe->lfe_fe_fd, FE_READ_BER, &u32))
-        mmi->tii_stats.ber = u32;
-      else {
-        ioctl_bad(lfe, 5);
-        if (logit)
-          tvhwarn(LS_LINUXDVB, "Unable to provide BER value.");
-      }
-    }
     
     /* SNR */
-    gotprop = 0;
     if(ioctl_check(lfe, 6) && fe_properties[3].u.st.len > 0) {
       if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_RELATIVE) {
         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
         mmi->tii_stats.snr = sig_multiply(fe_properties[3].u.st.stat[0].uvalue, lfe->lfe_snr_multiplier);
-        gotprop = 1;
       }
       else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_DECIBEL) {
         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_DECIBEL;
         mmi->tii_stats.snr = sig_multiply(fe_properties[3].u.st.stat[0].svalue, lfe->lfe_snr_multiplier);
-        gotprop = 1;
       }
       else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
         mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
-        gotprop = 1;
       }
       else {
         ioctl_bad(lfe, 6);
@@ -1137,27 +1120,18 @@ linuxdvb_frontend_monitor ( void *aux )
                   fe_properties[3].u.st.stat[0].scale);
       }
     }
-    if(!gotprop && ioctl_check(lfe, 7)) {
-      /* try old API */
-      if (!ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) {
-        mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE;
-        mmi->tii_stats.snr = sig_multiply(u16, lfe->lfe_snr_multiplier);
-      }
-      else {
-        ioctl_bad(lfe, 7);
-        mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
-        if (logit)
-          tvhwarn(LS_LINUXDVB, "Unable to provide SNR value.");
-      }
+    if(ioctl_check(lfe, 7)) {
+      ioctl_bad(lfe, 7);
+      mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN;
+      if (logit)
+        tvhwarn(LS_LINUXDVB, "Unable to provide SNR value.");
     }
 
     /* ERROR_BLOCK_COUNT == Uncorrected blocks (UNC) */
-    gotprop = 0;
     if(ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) {
       if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) {
         atomic_set(&mmi->tii_stats.unc, fe_properties[4].u.st.stat[0].uvalue);
         mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue;
-        gotprop = 1;
       }
       else {
         ioctl_bad(lfe, 8);
@@ -1168,11 +1142,9 @@ linuxdvb_frontend_monitor ( void *aux )
     }
 
     /* TOTAL_BLOCK_COUNT */
-    if(gotprop && (fe_properties[5].u.st.len > 0)) {
-      gotprop = 0;
+    if(fe_properties[5].u.st.len > 0) {
       if(ioctl_check(lfe, 9) && fe_properties[5].u.st.stat[0].scale == FE_SCALE_COUNTER) {
         mmi->tii_stats.tc_block = fe_properties[5].u.st.stat[0].uvalue;
-        gotprop = 1;
       }
       else {
         ioctl_bad(lfe, 9);
@@ -1184,17 +1156,10 @@ linuxdvb_frontend_monitor ( void *aux )
                  fe_properties[5].u.st.stat[0].scale);
       }
     }
-    if(!gotprop && ioctl_check(lfe, 10)) {
-      /* try old API */
-      if (!ioctl(lfe->lfe_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &u32)) {
-        atomic_set(&mmi->tii_stats.unc, u32);
-        gotprop = 1;
-      }
-      else {
-        ioctl_bad(lfe, 10);
-        if (logit)
-          tvhwarn(LS_LINUXDVB, "Unable to provide UNC value.");
-      }
+    if(ioctl_check(lfe, 10)) {
+      ioctl_bad(lfe, 10);
+      if (logit)
+        tvhwarn(LS_LINUXDVB, "Unable to provide UNC value.");
     }
   /* Older API */
   } else
