Permalink
Browse files

eDVBFrontend: use DVB API 5.10 to readFrontendData

On kernels with DVB API 5.10 or greater it is possible to query drivers and get advanced statistics back like DTV_STAT_CNR scaled as FE_SCALE_DECIBEL (aka signalQualitydB).

Currently only signalQuality,signalQualitydB (DTV_STAT_CNR) and signalPower (DTV_STAT_SIGNAL_STRENGTH) implemented on readFrontendData with care to make it backwards compatible (runtime and compile time). Also when new API is available and new statistics are not implemented again it will fallback to old DVB API.

TODO implement bitErrorRate using new DVB API (DTV_STAT_POST_ERROR_BIT_COUNT, DTV_STAT_POST_TOTAL_BIT_COUNT).

(cherry picked from commit 90cc295)
Signed-off-by: Erik Slagter <erik@openpli.org>
  • Loading branch information...
1 parent 0bf4dec commit 4221fd64903c38632726234c657cb9b043797834 @athoik athoik committed with eriksl Mar 4, 2016
Showing with 58 additions and 4 deletions.
  1. +58 −4 lib/dvb/frontend.cpp
View
@@ -1070,13 +1070,43 @@ int eDVBFrontend::readFrontendData(int type)
}
break;
case iFrontendInformation_ENUMS::signalQuality:
- case iFrontendInformation_ENUMS::signalQualitydB: /* this will move into the driver */
+ case iFrontendInformation_ENUMS::signalQualitydB: /* this moved into the driver on DVB API 5.10 */
if (m_state == stateLock)
{
- int snr = readFrontendData(iFrontendInformation_ENUMS::snrValue);
int signalquality = 0;
int signalqualitydb = 0;
- calculateSignalQuality(snr, signalquality, signalqualitydb);
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 10
+ if (m_dvbversion >= DVB_VERSION(5, 10))
+ {
+ dtv_property prop[1];
+ prop[0].cmd = DTV_STAT_CNR;
+ dtv_properties props;
+ props.props = prop;
+ props.num = 1;
+
+ if (::ioctl(m_fd, FE_GET_PROPERTY, &props) < 0 && errno != ERANGE)
+ {
+ eDebug("[eDVBFrontend] DTV_STAT_CNR failed: %m");
+ }
+ else
+ {
+ for(unsigned int i=0; i<prop[0].u.st.len; i++)
+ {
+ if (prop[0].u.st.stat[i].scale == FE_SCALE_DECIBEL)
+ signalqualitydb = prop[0].u.st.stat[i].svalue / 10;
+ else if (prop[0].u.st.stat[i].scale == FE_SCALE_RELATIVE)
+ signalquality = prop[0].u.st.stat[i].svalue;
+ }
+ }
+ }
+#endif
+ // fallback to old DVB API
+ if(!signalquality && !signalqualitydb)
+ {
+ int snr = readFrontendData(iFrontendInformation_ENUMS::snrValue);
+ calculateSignalQuality(snr, signalquality, signalqualitydb);
+ }
+
if (type == iFrontendInformation_ENUMS::signalQuality)
{
return signalquality;
@@ -1093,7 +1123,31 @@ int eDVBFrontend::readFrontendData(int type)
uint16_t strength=0;
if (!m_simulate)
{
- if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 10
+ if (m_dvbversion >= DVB_VERSION(5, 10))
+ {
+ dtv_property prop[1];
+ prop[0].cmd = DTV_STAT_SIGNAL_STRENGTH;
+ dtv_properties props;
+ props.props = prop;
+ props.num = 1;
+
+ if (::ioctl(m_fd, FE_GET_PROPERTY, &props) < 0 && errno != ERANGE)
+ {
+ eDebug("[eDVBFrontend] DTV_STAT_SIGNAL_STRENGTH failed: %m");
+ }
+ else
+ {
+ for(unsigned int i=0; i<prop[0].u.st.len; i++)
+ {
+ if (prop[0].u.st.stat[i].scale == FE_SCALE_RELATIVE)
+ strength = prop[0].u.st.stat[i].uvalue;
+ }
+ }
+ }
+#endif
+ // fallback to old DVB API
+ if (!strength && ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
eDebug("[eDVBFrontend] FE_READ_SIGNAL_STRENGTH failed: %m");
}
return strength;

0 comments on commit 4221fd6

Please sign in to comment.