+#include <linux/dvb/version.h>
+
#include <lib/dvb/dvb.h>
#include <lib/dvb/frontendparms.h>
#include <lib/base/eerror.h>
eDVBFrontendParametersTerrestrial oterrestrial;
if (parm->getDVBT(oterrestrial))
return -2;
-
if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
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;
DEFINE_REF(eDVBFrontend);
int eDVBFrontend::PriorityOrder=0;
+int eDVBFrontend::PreferredFrontendIndex=-1;
+
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_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
PutToDict(dict, "hierarchy_information", feparm.hierarchy);
PutToDict(dict, "inversion", feparm.inversion);
PutToDict(dict, "system", feparm.system);
- PutToDict(dict, "plp_id", feparm.plpid);
+ if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
+ {
+ PutToDict(dict, "plp_id", feparm.plpid);
+ }
}
void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
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)
// inner fec
switch (p[3].u.data)
{
- case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None;
- case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2;
- case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3;
- case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4;
- case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6;
- case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8;
- case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9;
+ 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;
+ 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;
- case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32;
- case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64;
- case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128;
- case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256;
+ 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;
+ 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;
- case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On;
+ case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
+ case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
default:
- case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
+ case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
}
PutToDict(dict, "inversion", tmp);
}
// system
switch (p[0].u.data)
{
- default:
- case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T;
- case SYS_DVBT2: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2;
+ 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/1000;
+ tmp = p[1].u.data;
PutToDict(dict, "frequency", tmp);
// bandwidth
switch (p[2].u.data)
// inversion
switch (p[9].u.data)
{
- case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off;
- case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On;
+ case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
+ case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
default:
- case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
+ case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
}
PutToDict(dict, "inversion", tmp);
-#ifdef DTV_DVBT2_PLP_ID
- tmp = p[10].u.data;
- PutToDict(dict, "plp_id", tmp);
-#endif
}
#else // #if HAVE_DVB_API_VERSION >= 5
{
if (dest && PyDict_Check(dest))
{
+ FRONTENDPARAMETERS front;
+#if HAVE_DVB_API_VERSION >= 5
struct dtv_property p[16];
struct dtv_properties cmdseq;
cmdseq.props = p;
cmdseq.num = 0;
- FRONTENDPARAMETERS front;
+ 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
+ else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<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;
-#ifdef DTV_DVBT2_PLP_ID
- p[10].cmd = DTV_DVBT2_PLP_ID;
- cmdseq.num = 11;
-#else
- cmdseq.num = 10;
-#endif
- break;
- }
- if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
- {
- eDebug("FE_GET_PROPERTY failed (%m)");
- original = true;
- }
+ eDebug("FE_GET_PROPERTY failed (%m)");
+ original = true;
+ }
+ 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)
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)
{
PutToDict(dest, "inversion", tmp);
switch(m_type)
{
-#if HAVE_DVB_API_VERSION >= 5
- case feSatellite:
- fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
- case feCable:
- fillDictWithCableData(dest, p);
- break;
- case feTerrestrial:
- fillDictWithTerrestrialData(dest, p);
- break;
-#else
case feSatellite:
fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
break;
case feTerrestrial:
fillDictWithTerrestrialData(dest, parm);
break;
-#endif
}
+#endif
}
}
}
}
else if (m_type == iDVBFrontend::feCable)
{
- struct dtv_property p[7];
+ struct dtv_property p[8];
struct dtv_properties cmdseq;
cmdseq.props = p;
p[0].cmd = DTV_CLEAR;
- p[1].cmd = DTV_FREQUENCY, p[1].u.data = parm_frequency;
- p[2].cmd = DTV_MODULATION, p[2].u.data = parm_u_qam_modulation;
- p[3].cmd = DTV_SYMBOL_RATE, p[3].u.data = parm_u_qam_symbol_rate;
- p[4].cmd = DTV_INNER_FEC, p[4].u.data = parm_u_qam_fec_inner;
- p[5].cmd = DTV_INVERSION, p[5].u.data = parm_inversion;
- p[6].cmd = DTV_TUNE;
- cmdseq.num = 7;
+#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");
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++;
- p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
-#ifdef DTV_DVBT2_PLP_ID
+#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");
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",
+ 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_transmission_mode,
parm_u_ofdm_guard_interval,
parm_u_ofdm_hierarchy_information,
- parm_inversion);
+ parm_inversion,
+ feparm.system,
+ feparm.plpid);
oparm.ter = feparm;
return 0;
}
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)
{
eDVBFrontendParametersTerrestrial ter_parm;
- if ( feparm->getDVBT(ter_parm) )
+ if (feparm->getDVBT(ter_parm) < 0)
{
return 0;
}
- if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
+ if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !m_can_handle_dvbt2)
{
- return m_can_handle_dvbt2 ? 1 : 0;
+ return 0;
}
- else // DVB-T
+ score = 2;
+ if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && m_can_handle_dvbt2)
{
- return m_can_handle_dvbt2 ? 1 : 2;
+ /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
+ score--;
}
}
- return 0;
+
+ if (score && preferred)
+ {
+ /* make 'sure' we always prefer this frontend */
+ score += 100000;
+ }
+
+ return score;
}
bool eDVBFrontend::setSlotInfo(ePyObject obj)