Update httpstream
[vuplus_dvbapp] / lib / dvb / frontend.cpp
index 47e1ab5..a183e37 100755 (executable)
@@ -1,3 +1,5 @@
+#include <linux/dvb/version.h>
+
 #include <lib/dvb/dvb.h>
 #include <lib/dvb/frontendparms.h>
 #include <lib/base/eerror.h>
@@ -213,27 +215,67 @@ void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descr
 
 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
 {
+       /* EN 300 468 V1.11.1 DVB-SI SPEC */
        frequency = descriptor.getCentreFrequency() * 10;
-       bandwidth = descriptor.getBandwidth();
-       if ( bandwidth > 2 ) // 5Mhz forced to auto
-               bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto;
-       code_rate_HP = descriptor.getCodeRateHpStream();
-       if (code_rate_HP > 4)
-               code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto;
-       code_rate_LP = descriptor.getCodeRateLpStream();
-       if (code_rate_LP > 4)
-               code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto;
-       transmission_mode = descriptor.getTransmissionMode();
-       if (transmission_mode > 1) // TM4k forced to auto
-               transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto;
-       guard_interval = descriptor.getGuardInterval();
-       if (guard_interval > 3)
-               guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto;
+       switch (descriptor.getBandwidth())
+       {
+               case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
+               case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
+               case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
+               case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
+               case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
+               case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
+               default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
+       }
+       switch (descriptor.getCodeRateHpStream())
+       {
+               case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
+               case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
+               case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
+               case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
+               case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
+               default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
+       }
+       switch (descriptor.getCodeRateLpStream())
+       {
+               case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
+               case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
+               case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
+               case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
+               case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
+               default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
+       }
+       switch (descriptor.getTransmissionMode())
+       {
+               case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
+               case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
+               case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
+               case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
+               case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
+               case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
+               default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
+       }
+       switch (descriptor.getGuardInterval())
+       {
+               case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
+               case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
+               case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
+               case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
+               case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
+               case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
+               case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
+               default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
+       }
+//     hierarchy = descriptor.getHierarchyInformation();
        hierarchy = descriptor.getHierarchyInformation()&3;
+       if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
+               hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
        modulation = descriptor.getConstellation();
-       if (modulation > 2)
+       if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
                modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
        inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
+       system = eDVBFrontendParametersTerrestrial::System_DVB_T;
+       plpid = 0;
        eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
                frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
                guard_interval, hierarchy, modulation);
@@ -357,7 +399,6 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
                eDVBFrontendParametersTerrestrial oterrestrial;
                if (parm->getDVBT(oterrestrial))
                        return -2;
-
                if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
                        oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
                        terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
@@ -386,6 +427,11 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
                        oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
                        terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
                        diff = 1 << 30;
+               else if (oterrestrial.system != terrestrial.system)
+                       diff = 1 << 30;
+               else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
+                       oterrestrial.plpid != terrestrial.plpid)
+                       diff = 1 << 30;
                else
                        diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
                return 0;
@@ -452,10 +498,12 @@ RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
 DEFINE_REF(eDVBFrontend);
 
 int eDVBFrontend::PriorityOrder=0;
+int eDVBFrontend::PreferredFrontendIndex=-1;
 
-eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate)
-       :m_simulate(simulate), m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe)
-       ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false)
+
+eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
+       :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
+       ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false), m_can_handle_dvbt2(false)
        ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
 #if HAVE_DVB_API_VERSION < 3
        ,m_secfd(-1)
@@ -490,11 +538,6 @@ void eDVBFrontend::reopenFrontend()
        openFrontend();
 }
 
-#ifdef BUILD_VUPLUS /* ikseong */
-int frontend0_fd;
-int frontend1_fd;
-#endif
-
 int eDVBFrontend::openFrontend()
 {
        if (m_state != stateClosed)
@@ -508,10 +551,10 @@ int eDVBFrontend::openFrontend()
 #else
        dvb_frontend_info fe_info;
 #endif
-       eDebugNoSimulate("opening frontend %d", m_dvbid);
-       if (m_fd < 0)
+       if (!m_simulate)
        {
-               if (!m_simulate || m_type == -1)
+               eDebug("opening frontend %d", m_dvbid);
+               if (m_fd < 0)
                {
                        m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
                        if (m_fd < 0)
@@ -519,80 +562,70 @@ int eDVBFrontend::openFrontend()
                                eWarning("failed! (%s) %m", m_filename);
                                return -1;
                        }
-#ifdef BUILD_VUPLUS /* ikseong */
-                       else
-                       {                               
-                               if (m_dvbid==0)
-                                       frontend0_fd = m_fd;
-                               else if (m_dvbid==1)
-                                       frontend1_fd = m_fd;
-                       }
-#endif
                }
-       }
-       else
-               eWarning("frontend %d already opened", m_dvbid);
-       if (m_type == -1)
-       {
-               if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
+               else
+                       eWarning("frontend %d already opened", m_dvbid);
+               if (m_type == -1)
                {
-                       eWarning("ioctl FE_GET_INFO failed");
-                       ::close(m_fd);
-                       m_fd = -1;
-                       return -1;
-               }
+                       if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
+                       {
+                               eWarning("ioctl FE_GET_INFO failed");
+                               ::close(m_fd);
+                               m_fd = -1;
+                               return -1;
+                       }
 
-               switch (fe_info.type)
-               {
-               case FE_QPSK:
-                       m_type = iDVBFrontend::feSatellite;
-                       break;
-               case FE_QAM:
-                       m_type = iDVBFrontend::feCable;
-                       break;
-               case FE_OFDM:
-                       m_type = iDVBFrontend::feTerrestrial;
-                       break;
-               default:
-                       eWarning("unknown frontend type.");
-                       ::close(m_fd);
-                       m_fd = -1;
-                       return -1;
+                       switch (fe_info.type)
+                       {
+                       case FE_QPSK:
+                               m_type = iDVBFrontend::feSatellite;
+                               break;
+                       case FE_QAM:
+                               m_type = iDVBFrontend::feCable;
+                               break;
+                       case FE_OFDM:
+                               m_type = iDVBFrontend::feTerrestrial;
+                               break;
+                       default:
+                               eWarning("unknown frontend type.");
+                               ::close(m_fd);
+                               m_fd = -1;
+                               return -1;
+                       }
+                       if (m_simulate_fe)
+                               m_simulate_fe->m_type = m_type;
+                       eDebugNoSimulate("detected %s frontend", "satellite\0cable\0    terrestrial"+fe_info.type*10);
                }
-               eDebugNoSimulate("detected %s frontend", "satellite\0cable\0    terrestrial"+fe_info.type*10);
-       }
 
 #if HAVE_DVB_API_VERSION < 3
-       if (m_type == iDVBFrontend::feSatellite)
-       {
-                       if (m_secfd < 0)
-                       {
-                               if (!m_simulate)
+               if (m_type == iDVBFrontend::feSatellite)
+               {
+                               if (m_secfd < 0)
                                {
-                                       m_secfd = ::open(m_sec_filename, O_RDWR);
-                                       if (m_secfd < 0)
+                                       if (!m_simulate)
                                        {
-                                               eWarning("failed! (%s) %m", m_sec_filename);
-                                               ::close(m_fd);
-                                               m_fd=-1;
-                                               return -1;
+                                               m_secfd = ::open(m_sec_filename, O_RDWR);
+                                               if (m_secfd < 0)
+                                               {
+                                                       eWarning("failed! (%s) %m", m_sec_filename);
+                                                       ::close(m_fd);
+                                                       m_fd=-1;
+                                                       return -1;
+                                               }
                                        }
                                }
-                       }
-                       else
-                               eWarning("sec %d already opened", m_dvbid);
-       }
+                               else
+                                       eWarning("sec %d already opened", m_dvbid);
+               }
 #endif
 
-       setTone(iDVBFrontend::toneOff);
-       setVoltage(iDVBFrontend::voltageOff);
-
-       if (!m_simulate)
-       {
                m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
                CONNECT(m_sn->activated, eDVBFrontend::feEvent);
        }
 
+       setTone(iDVBFrontend::toneOff);
+       setVoltage(iDVBFrontend::voltageOff);
+
        return 0;
 }
 
@@ -753,7 +786,7 @@ void eDVBFrontend::timeout()
        m_tuning = 0;
        if (m_state == stateTuning)
        {
-#ifdef BUILD_VUPLUS /* ikseong  */
+#ifdef BUILD_VUPLUS
                eDVBFrontend *sec_fe = this;
                sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
 #endif
@@ -1070,6 +1103,11 @@ void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial
        PutToDict(dict, "guard_interval", feparm.guard_interval);
        PutToDict(dict, "hierarchy_information", feparm.hierarchy);
        PutToDict(dict, "inversion", feparm.inversion);
+       PutToDict(dict, "system", feparm.system);
+       if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
+       {
+               PutToDict(dict, "plp_id", feparm.plpid);
+       }
 }
 
 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
@@ -1144,9 +1182,187 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &
        case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
        }
        PutToDict(dict, "modulation", tmp);
+
+       switch(parm_inversion & 3)
+       {
+               case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
+               case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
+               default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
+       }
+       PutToDict(dict, "inversion", tmp);
+}
+
+static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
+{
+       long tmp = 0;
+// frequency
+       tmp = p[1].u.data/1000;
+       PutToDict(dict, "frequency", tmp);
+// sysbolrate
+       PutToDict(dict, "symbol_rate", p[2].u.data);
+// inner fec
+       switch (p[3].u.data)
+       {
+               case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
+               case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
+               case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
+               case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
+               case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
+               case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
+               case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
+               default:
+               case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
+       }
+       PutToDict(dict, "fec_inner", tmp);
+// modulation
+       switch (p[4].u.data)
+       {
+               case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
+               case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
+               case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
+               case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
+               case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
+               default:
+               case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
+       }
+       PutToDict(dict, "modulation", tmp);
+// inversion
+       switch (p[5].u.data)
+       {
+               case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
+               case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
+               default:
+               case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
+       }
+       PutToDict(dict, "inversion", tmp);
 }
 
-#else
+static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
+{
+       long tmp =0;
+// system
+       switch (p[0].u.data)
+       {
+               default: eDebug("got unsupported system from frontend! report as DVBT!");
+               case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
+               case SYS_DVBT2:
+               {
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
+                       tmp = p[10].u.data;
+                       PutToDict(dict, "plp_id", tmp);
+#endif
+                       tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
+               }
+       }
+       PutToDict(dict, "system", tmp);
+// frequency
+       tmp = p[1].u.data;
+       PutToDict(dict, "frequency", tmp);
+// bandwidth
+       switch (p[2].u.data)
+       {
+               case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
+               case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
+               case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
+               case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
+               case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
+               case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
+               default:
+               case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
+       }
+       PutToDict(dict, "bandwidth", tmp);
+// code rate LP
+       switch (p[3].u.data)
+       {
+               case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
+               case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
+               case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
+               case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
+               case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
+               case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
+               case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
+               case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
+               default:
+               case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
+       }
+       PutToDict(dict, "code_rate_lp", tmp);
+// code rate HP
+       switch (p[4].u.data)
+       {
+               case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
+               case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
+               case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
+               case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
+               case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
+               case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
+               case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
+               case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
+               default:
+               case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
+       }
+       PutToDict(dict, "code_rate_hp", tmp);
+// constellation
+       switch (p[5].u.data)
+       {
+               case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
+               case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
+               case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
+               case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
+               default:
+               case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
+       }
+       PutToDict(dict, "constellation", tmp);
+
+// transmission
+       switch (p[6].u.data)
+       {
+       case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
+       case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
+       case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
+       case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
+       case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
+       case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
+       default:
+       case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
+       }
+       PutToDict(dict, "transmission_mode", tmp);
+// guard interval
+       switch (p[7].u.data)
+       {
+               case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
+               case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
+               case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
+               case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
+               case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
+               case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
+               case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
+               default:
+               case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
+       }
+       PutToDict(dict, "guard_interval", tmp);
+// hierarchy
+       switch (p[8].u.data)
+       {
+               case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
+               case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
+               case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
+               case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
+               default:
+               case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
+       }
+       PutToDict(dict, "hierarchy_information", tmp);
+// inversion
+       switch (p[9].u.data)
+       {
+               case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off;  break;
+               case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On;  break;
+               default:
+               case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown;  break;
+       }
+       PutToDict(dict, "inversion", tmp);
+}
+
+#else // #if HAVE_DVB_API_VERSION >= 5
 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
 {
        long tmp=0;
@@ -1220,7 +1436,6 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &
 #endif
        PutToDict(dict, "system", tmp);
 }
-#endif
 
 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
 {
@@ -1333,6 +1548,8 @@ static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS
        PutToDict(dict, "hierarchy_information", tmp);
 }
 
+#endif // #if HAVE_DVB_API_VERSION >= 5
+
 void eDVBFrontend::getFrontendStatus(ePyObject dest)
 {
        if (dest && PyDict_Check(dest))
@@ -1382,30 +1599,74 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
        {
                FRONTENDPARAMETERS front;
 #if HAVE_DVB_API_VERSION >= 5
-               struct dtv_property p[4];
+               struct dtv_property p[16];
                struct dtv_properties cmdseq;
                cmdseq.props = p;
-               cmdseq.num = 4;
-               p[0].cmd = DTV_DELIVERY_SYSTEM;
-               p[1].cmd = DTV_MODULATION;
-               p[2].cmd = DTV_ROLLOFF;
-               p[3].cmd = DTV_PILOT;
+               cmdseq.num = 0;
+               switch(m_type)
+               {
+                       case feSatellite:
+                               p[0].cmd = DTV_DELIVERY_SYSTEM;
+                               p[1].cmd = DTV_MODULATION;
+                               p[2].cmd = DTV_ROLLOFF;
+                               p[3].cmd = DTV_PILOT;
+                               cmdseq.num = 4;
+                               break;
+                       case feCable:
+                               p[0].cmd = DTV_DELIVERY_SYSTEM;
+                               p[1].cmd = DTV_FREQUENCY;
+                               p[2].cmd = DTV_SYMBOL_RATE;
+                               p[3].cmd = DTV_INNER_FEC;
+                               p[4].cmd = DTV_MODULATION;
+                               p[5].cmd = DTV_INVERSION;
+                               cmdseq.num = 6;
+                               break;
+                       case feTerrestrial:
+                               p[0].cmd = DTV_DELIVERY_SYSTEM;
+                               p[1].cmd = DTV_FREQUENCY;
+                               p[2].cmd = DTV_BANDWIDTH_HZ;
+                               p[3].cmd = DTV_CODE_RATE_LP;
+                               p[4].cmd = DTV_CODE_RATE_HP;
+                               p[5].cmd = DTV_MODULATION;
+                               p[6].cmd = DTV_TRANSMISSION_MODE;
+                               p[7].cmd = DTV_GUARD_INTERVAL;
+                               p[8].cmd = DTV_HIERARCHY;
+                               p[9].cmd = DTV_INVERSION;
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
+                               p[10].cmd = DTV_STREAM_ID;
+                               cmdseq.num = 11;
+#elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
+                               p[10].cmd = DTV_DVBT2_PLP_ID;
+                               cmdseq.num = 11;
+#else
+                               cmdseq.num = 10;
+#endif
+                               break;
+               }
 #endif
                if (m_simulate || m_fd == -1 || original)
+               {
                        original = true;
+               }
 #if HAVE_DVB_API_VERSION >= 5
-               else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only
-                       ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
+               else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
                {
                        eDebug("FE_GET_PROPERTY failed (%m)");
                        original = true;
                }
-#endif
+               else if (m_type == feSatellite && // use for DVB-S(2) only
+                       ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
+               {
+                       eDebug("FE_GET_FRONTEND failed (%m)");
+                       original = true;
+               }
+#else
                else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
                {
                        eDebug("FE_GET_FRONTEND failed (%m)");
                        original = true;
                }
+#endif
                if (original)
                {
                        switch(m_type)
@@ -1424,6 +1685,20 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
                else
                {
                        FRONTENDPARAMETERS &parm = front;
+#if HAVE_DVB_API_VERSION >= 5
+                       switch(m_type)
+                       {
+                               case feSatellite:
+                                       fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
+                                       break;
+                               case feCable:
+                                       fillDictWithCableData(dest, p);
+                                       break;
+                               case feTerrestrial:
+                                       fillDictWithTerrestrialData(dest, p);
+                                       break;
+                       }
+#else
                        long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
                        switch(parm_inversion & 3)
                        {
@@ -1439,11 +1714,7 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
                        switch(m_type)
                        {
                                case feSatellite:
-#if HAVE_DVB_API_VERSION >= 5
-                                       fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
-#else
                                        fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
-#endif
                                        break;
                                case feCable:
                                        fillDictWithCableData(dest, parm);
@@ -1452,6 +1723,7 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
                                        fillDictWithTerrestrialData(dest, parm);
                                        break;
                        }
+#endif
                }
        }
 }
@@ -1995,6 +2267,78 @@ void eDVBFrontend::setFrontend(bool recvEvents)
                                return;
                        }
                }
+               else if (m_type == iDVBFrontend::feCable)
+               {
+                       struct dtv_property p[8];
+                       struct dtv_properties cmdseq;
+                       cmdseq.props = p;
+                       p[0].cmd = DTV_CLEAR;
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
+                       p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
+#else
+                       p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
+#endif
+                       p[2].cmd = DTV_FREQUENCY,       p[2].u.data = parm_frequency;
+                       p[3].cmd = DTV_MODULATION,      p[3].u.data = parm_u_qam_modulation;
+                       p[4].cmd = DTV_SYMBOL_RATE,     p[4].u.data = parm_u_qam_symbol_rate;
+                       p[5].cmd = DTV_INNER_FEC,       p[5].u.data = parm_u_qam_fec_inner;
+                       p[6].cmd = DTV_INVERSION,       p[6].u.data = parm_inversion;
+                       p[7].cmd = DTV_TUNE;
+                       cmdseq.num = 8;
+                       if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
+                       {
+                               perror("FE_SET_PROPERTY failed");
+                               return;
+                       }
+               }
+               else if (m_type == iDVBFrontend::feTerrestrial)
+               {
+                       fe_delivery_system_t system = SYS_DVBT;
+                       switch (oparm.ter.system)
+                       {
+                               default:
+                               case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
+                               case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
+                       }
+                       int bandwidth = 0;
+                       switch (oparm.ter.bandwidth)
+                       {
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
+                               default:
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
+                               case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
+                       }
+                       struct dtv_property p[13];
+                       struct dtv_properties cmdseq;
+                       cmdseq.props = p;
+                       cmdseq.num = 0;
+                       p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_FREQUENCY,      p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_CODE_RATE_LP,   p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_CODE_RATE_HP,   p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_MODULATION,     p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE,      p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_HIERARCHY,      p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ,   p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
+                       p[cmdseq.num].cmd = DTV_INVERSION,      p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
+                       p[cmdseq.num].cmd = DTV_STREAM_ID       ,       p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
+#elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
+                       p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID    ,       p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
+#endif
+                       p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
+                       if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
+                       {
+                               perror("FE_SET_PROPERTY failed");
+                               return;
+                       }
+               }
                else
 #endif
                {
@@ -2249,6 +2593,15 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
        case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
                parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
                break;
+       case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
+               parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
+               break;
+       case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
+               parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
+               break;
+       case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
+               parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
+               break;
        default:
        case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
                parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
@@ -2271,6 +2624,12 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
        case eDVBFrontendParametersTerrestrial::FEC_7_8:
                parm_u_ofdm_code_rate_LP = FEC_7_8;
                break;
+       case eDVBFrontendParametersTerrestrial::FEC_6_7:
+               parm_u_ofdm_code_rate_LP = FEC_6_7;
+               break;
+       case eDVBFrontendParametersTerrestrial::FEC_8_9:
+               parm_u_ofdm_code_rate_LP = FEC_8_9;
+               break;
        default:
        case eDVBFrontendParametersTerrestrial::FEC_Auto:
                parm_u_ofdm_code_rate_LP = FEC_AUTO;
@@ -2293,6 +2652,12 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
        case eDVBFrontendParametersTerrestrial::FEC_7_8:
                parm_u_ofdm_code_rate_HP = FEC_7_8;
                break;
+       case eDVBFrontendParametersTerrestrial::FEC_6_7:
+               parm_u_ofdm_code_rate_HP = FEC_6_7;
+               break;
+       case eDVBFrontendParametersTerrestrial::FEC_8_9:
+               parm_u_ofdm_code_rate_HP = FEC_8_9;
+               break;
        default:
        case eDVBFrontendParametersTerrestrial::FEC_Auto:
                parm_u_ofdm_code_rate_HP = FEC_AUTO;
@@ -2309,6 +2674,9 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
        case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
                parm_u_ofdm_constellation = QAM_64;
                break;
+       case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
+               parm_u_ofdm_constellation = QAM_256;
+               break;
        default:
        case eDVBFrontendParametersTerrestrial::Modulation_Auto:
                parm_u_ofdm_constellation = QAM_AUTO;
@@ -2322,6 +2690,18 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
        case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
                parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
                break;
+       case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
+               parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
+               break;
+       case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
+               parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
+               break;
+       case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
+               parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
+               break;
+       case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
+               parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
+               break;
        default:
        case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
                parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
@@ -2341,6 +2721,15 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
                case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
                        parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
                        break;
+               case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
+                       parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
+                       break;
+               case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
+                       parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
+                       break;
+               case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
+                       parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
+                       break;
                default:
                case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
                        parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
@@ -2378,6 +2767,18 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial
                parm_inversion = INVERSION_AUTO;
                break;
        }
+       eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d, system %d, plpid %d",
+               parm_frequency/1000,
+               parm_u_ofdm_bandwidth,
+               parm_u_ofdm_code_rate_LP,
+               parm_u_ofdm_code_rate_HP,
+               parm_u_ofdm_constellation,
+               parm_u_ofdm_transmission_mode,
+               parm_u_ofdm_guard_interval,
+               parm_u_ofdm_hierarchy_information,
+               parm_inversion,
+               feparm.system,
+               feparm.plpid);
        oparm.ter = feparm;
        return 0;
 }
@@ -2694,40 +3095,82 @@ RESULT eDVBFrontend::setData(int num, long val)
 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
 {
        int type;
+       int score = 0;
+       bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
+
        if (feparm->getSystem(type) || type != m_type || !m_enabled)
                return 0;
+
        if (m_type == eDVBFrontend::feSatellite)
        {
-               ASSERT(m_sec);
                eDVBFrontendParametersSatellite sat_parm;
-               int ret = feparm->getDVBS(sat_parm);
-               ASSERT(!ret);
+               if (feparm->getDVBS(sat_parm) < 0)
+               {
+                       return 0;
+               }
                if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
+               {
                        return 0;
-               ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
-               if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
-                       ret -= 1;
-               return ret;
+               }
+               score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
+               if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
+               {
+                       /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
+                       score--;
+               }
        }
+
        else if (m_type == eDVBFrontend::feCable)
-               return 2;  // more prio for cable frontends
+       {
+               eDVBFrontendParametersCable cab_parm;
+               if (feparm->getDVBC(cab_parm) < 0)
+               {
+                       return 0;
+               }
+               score = 2;
+       }
+
        else if (m_type == eDVBFrontend::feTerrestrial)
-               return 1;
-       return 0;
+       {
+               eDVBFrontendParametersTerrestrial ter_parm;
+               if (feparm->getDVBT(ter_parm) < 0)
+               {
+                       return 0;
+               }
+               if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !m_can_handle_dvbt2)
+               {
+                       return 0;
+               }
+               score = 2;
+               if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && m_can_handle_dvbt2)
+               {
+                       /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
+                       score--;
+               }
+       }
+
+       if (score && preferred)
+       {
+               /* make 'sure' we always prefer this frontend */
+               score += 100000;
+       }
+
+       return score;
 }
 
 bool eDVBFrontend::setSlotInfo(ePyObject obj)
 {
-       ePyObject Id, Descr, Enabled, IsDVBS2, frontendId;
-       if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5)
+       ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
+       if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
                goto arg_error;
        Id = PyTuple_GET_ITEM(obj, 0);
        Descr = PyTuple_GET_ITEM(obj, 1);
        Enabled = PyTuple_GET_ITEM(obj, 2);
        IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
-       frontendId = PyTuple_GET_ITEM(obj, 4);
+       IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
+       frontendId = PyTuple_GET_ITEM(obj, 5);
        m_slotid = PyInt_AsLong(Id);
-       if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId))
+       if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
                goto arg_error;
        strcpy(m_description, PyString_AS_STRING(Descr));
        if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
@@ -2742,8 +3185,9 @@ bool eDVBFrontend::setSlotInfo(ePyObject obj)
                !!strstr(m_description, "Alps -S") ||
                !!strstr(m_description, "BCM4501");
        m_can_handle_dvbs2 = IsDVBS2 == Py_True;
-       eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s",
-               m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" );
+       m_can_handle_dvbt2 = IsDVBT2 == Py_True;
+       eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
+               m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No", m_can_handle_dvbt2 ? "Yes" : "No" );
        return true;
 arg_error:
        PyErr_SetString(PyExc_StandardError,