+#include <linux/dvb/version.h>
+
#include <lib/dvb/dvb.h>
#include <lib/dvb/frontendparms.h>
#include <lib/base/eerror.h>
RESULT eDVBFrontendParameters::getSystem(int &t) const
{
- if (m_type == -1)
- return -1;
t = m_type;
- return 0;
+ return (m_type == -1) ? -1 : 0;
}
RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
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_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)
+ :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
+ ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
+ ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false), m_is_usbtuner(false)
#if HAVE_DVB_API_VERSION < 3
,m_secfd(-1)
#endif
void eDVBFrontend::reopenFrontend()
{
sleep(1);
- m_type = -1;
+ m_delsys.clear();
openFrontend();
}
}
else
eWarning("frontend %d already opened", m_dvbid);
- if (m_type == -1)
+
+ if (m_delsys.empty())
{
+#ifdef DTV_ENUM_DELSYS
+ struct dtv_property p[1];
+ p[0].cmd = DTV_ENUM_DELSYS;
+ struct dtv_properties cmdseq;
+ cmdseq.num = 1;
+ cmdseq.props = p;
+ if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0)
+ {
+ m_delsys.clear();
+ unsigned int i;
+ for (i = 0; i < p[0].u.buffer.len ; i++)
+ {
+ fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i];
+ m_delsys[delsys] = true;
+ }
+ }
+#else
if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
{
eWarning("ioctl FE_GET_INFO failed");
m_fd = -1;
return -1;
}
-
+ /* old DVB API, fill delsys map with some defaults */
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;
+ case FE_QPSK:
+ {
+ m_delsys[SYS_DVBS] = true;
+#if DVB_API_VERSION >= 5
+ if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
+#endif
+ break;
+ }
+ case FE_QAM:
+ {
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
+ m_delsys[SYS_DVBC_ANNEX_A] = true;
+#else
+ m_delsys[SYS_DVBC_ANNEX_AC] = true;
+#endif
+ break;
+ }
+ case FE_OFDM:
+ {
+ m_delsys[SYS_DVBT] = true;
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
+ if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
+#endif
+ break;
+ }
+ case FE_ATSC: // placeholder to prevent warning
+ {
+ break;
+ }
}
- if (m_simulate_fe)
- m_simulate_fe->m_type = m_type;
- eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
+#endif
}
-#if HAVE_DVB_API_VERSION < 3
- if (m_type == iDVBFrontend::feSatellite)
+ if (m_simulate_fe)
{
- if (m_secfd < 0)
- {
- if (!m_simulate)
- {
- 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);
+ m_simulate_fe->m_delsys = m_delsys;
}
-#endif
m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
CONNECT(m_sn->activated, eDVBFrontend::feEvent);
{
if (!no_delayed)
{
- m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
+ m_sec->prepareTurnOffSatCR(*this);
m_tuneTimer->start(0, true);
if(!m_tuneTimer->isActive())
{
eDebug("stateLostLock");
state = stateLostLock;
if (!m_rotor_mode)
+ {
sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
+ sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
+ }
}
}
if (m_state != state)
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
+ sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
#endif
m_state = stateFailed;
m_stateChanged(this);
float SDS_SNRE = snr << 16;
float snr_in_db;
- if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
+ eDVBFrontendParametersSatellite sparm;
+ oparm.getDVBS(sparm);
+
+ if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
{
static float SNR_COEFF[6] = {
100.0 / 4194304.0,
float fval1 = SDS_SNRE / 268435456.0,
fval2, fval3, fval4;
- if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
+ if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
{
fval2 = 6.76;
fval3 = 4.35;
{
if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
return snr;
- switch(m_type)
+
+ int type = -1;
+ oparm.getSystem(type);
+ switch(type)
{
case feSatellite:
return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
}
case frontendNumber:
return m_slotid;
+ case isUsbTuner:
+ return m_is_usbtuner;
}
return 0;
}
case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
case SYS_DVBT2:
{
-#ifdef DTV_DVBT2_PLP_ID
+#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
{
if (dest && PyDict_Check(dest))
{
+ int type = -1;
FRONTENDPARAMETERS front;
#if HAVE_DVB_API_VERSION >= 5
struct dtv_property p[16];
struct dtv_properties cmdseq;
cmdseq.props = p;
cmdseq.num = 0;
- switch(m_type)
+ oparm.getSystem(type);
+ switch(type)
{
case feSatellite:
p[0].cmd = DTV_DELIVERY_SYSTEM;
p[7].cmd = DTV_GUARD_INTERVAL;
p[8].cmd = DTV_HIERARCHY;
p[9].cmd = DTV_INVERSION;
-#ifdef DTV_DVBT2_PLP_ID
+#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
eDebug("FE_GET_PROPERTY failed (%m)");
original = true;
}
- else if (m_type == feSatellite && // use for DVB-S(2) only
+ else if (type == feSatellite && // use for DVB-S(2) only
ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
{
eDebug("FE_GET_FRONTEND failed (%m)");
#endif
if (original)
{
- switch(m_type)
+ switch(type)
{
case feSatellite:
- PutSatelliteDataToDict(dest, oparm.sat);
+ eDVBFrontendParametersSatellite sparm;
+ oparm.getDVBS(sparm);
+ PutSatelliteDataToDict(dest, sparm);
break;
case feCable:
- PutCableDataToDict(dest, oparm.cab);
+ eDVBFrontendParametersCable cparm;
+ oparm.getDVBC(cparm);
+ PutCableDataToDict(dest, cparm);
break;
case feTerrestrial:
- PutTerrestrialDataToDict(dest, oparm.ter);
+ eDVBFrontendParametersTerrestrial tparm;
+ oparm.getDVBT(tparm);
+ PutTerrestrialDataToDict(dest, tparm);
break;
}
}
{
FRONTENDPARAMETERS &parm = front;
#if HAVE_DVB_API_VERSION >= 5
- switch(m_type)
+ switch(type)
{
case feSatellite:
- fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
+ eDVBFrontendParametersSatellite sparm;
+ oparm.getDVBS(sparm);
+ fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
break;
case feCable:
fillDictWithCableData(dest, p);
break;
}
PutToDict(dest, "inversion", tmp);
- switch(m_type)
+ switch(type)
{
+ eDVBFrontendParametersSatellite sparm;
+ oparm.getDVBS(sparm);
case feSatellite:
- fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
+ fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
break;
case feCable:
fillDictWithCableData(dest, parm);
{
const char *tmp=0;
PutToDict(dest, "tuner_number", m_slotid);
- switch(m_type)
+
+ if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
{
- case feSatellite:
- tmp = "DVB-S";
- break;
- case feCable:
- tmp = "DVB-C";
- break;
- case feTerrestrial:
- tmp = "DVB-T";
- break;
- default:
- tmp = "UNKNOWN";
- break;
+ tmp = "DVB-S";
+ }
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
+ else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
+#else
+ else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
+#endif
+ {
+ tmp = "DVB-C";
+ }
+ else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
+ {
+ tmp = "DVB-T";
+ }
+ else
+ {
+ tmp = "UNKNOWN";
}
PutToDict(dest, "tuner_type", tmp);
}
tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
int state = sec_fe->m_state;
+#if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
// workaround to put the kernel frontend thread into idle state!
if (state != eDVBFrontend::stateIdle && state != stateClosed)
{
sec_fe->closeFrontend(true);
state = sec_fe->m_state;
}
+#endif
// sec_fe is closed... we must reopen it here..
if (state == stateClosed)
{
if (!m_simulate)
{
eDebug("setting frontend %d", m_dvbid);
+
+ int type = -1;
+ oparm.getSystem(type);
+
if (recvEvents)
m_sn->start();
feEvent(-1); // flush events
#if HAVE_DVB_API_VERSION >= 5
- if (m_type == iDVBFrontend::feSatellite)
+ if (type == iDVBFrontend::feSatellite)
{
fe_rolloff_t rolloff = ROLLOFF_35;
fe_pilot_t pilot = PILOT_OFF;
fe_modulation_t modulation = QPSK;
fe_delivery_system_t system = SYS_DVBS;
- switch(oparm.sat.system)
+ eDVBFrontendParametersSatellite sparm;
+ oparm.getDVBS(sparm);
+ switch(sparm.system)
{
case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
};
- switch(oparm.sat.modulation)
+ switch(sparm.modulation)
{
case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
};
- switch(oparm.sat.pilot)
+ switch(sparm.pilot)
{
case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
};
- switch(oparm.sat.rolloff)
+ switch(sparm.rolloff)
{
case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
return;
}
}
- else if (m_type == iDVBFrontend::feCable)
+ else if (type == iDVBFrontend::feCable)
{
struct dtv_property p[8];
struct dtv_properties cmdseq;
return;
}
}
- else if (m_type == iDVBFrontend::feTerrestrial)
+ else if (type == iDVBFrontend::feTerrestrial)
{
fe_delivery_system_t system = SYS_DVBT;
- switch (oparm.ter.system)
+ eDVBFrontendParametersTerrestrial tparm;
+ oparm.getDVBT(tparm);
+ switch (tparm.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)
+ switch (tparm.bandwidth)
{
case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
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++;
-#ifdef DTV_DVBT2_PLP_ID
- p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, 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 = tparm.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 = tparm.plpid, cmdseq.num++;
#endif
p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
}
}
else
-#endif
+#endif /* HAVE_DVB_API_VERSION >= 5 */
{
if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
{
}
}
-RESULT eDVBFrontend::getFrontendType(int &t)
-{
- if (m_type == -1)
- return -ENODEV;
- t = m_type;
- return 0;
-}
-
RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
{
int res;
}
eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
}
- oparm.sat = feparm;
+ oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
return res;
}
parm_u_qam_fec_inner,
parm_u_qam_modulation,
parm_inversion);
- oparm.cab = feparm;
+ oparm.setDVBC(feparm);
return 0;
}
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);
- oparm.ter = feparm;
+ parm_inversion,
+ feparm.system,
+ feparm.plpid);
+ oparm.setDVBT(feparm);
return 0;
}
int res=0;
- if (!m_sn && !m_simulate)
+ int type;
+ if (where.getSystem(type) < 0)
{
- eDebug("no frontend device opened... do not try to tune !!!");
- res = -ENODEV;
+ res = -EINVAL;
goto tune_error;
}
- if (m_type == -1)
+ if (!m_sn && !m_simulate)
{
+ eDebug("no frontend device opened... do not try to tune !!!");
res = -ENODEV;
goto tune_error;
}
where.calcLockTimeout(timeout);
- switch (m_type)
+ switch (type)
{
case feSatellite:
{
break;
}
+ default:
+ {
+ res = -EINVAL;
+ goto tune_error;
+ }
}
m_sec_sequence.current() = m_sec_sequence.begin();
RESULT eDVBFrontend::setVoltage(int voltage)
{
- if (m_type == feCable)
- return -1;
#if HAVE_DVB_API_VERSION < 3
secVoltage vlt;
#else
#if HAVE_DVB_API_VERSION < 3
return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
#else
- if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
- perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
+ ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
#endif
}
RESULT eDVBFrontend::setTone(int t)
{
- if (m_type != feSatellite)
- return -1;
#if HAVE_DVB_API_VERSION < 3
secToneMode_t tone;
#else
{
if (m_simulate)
return 0;
+
#if HAVE_DVB_API_VERSION < 3
struct secCommand cmd;
cmd.type = SEC_CMDTYPE_DISEQC_RAW;
return 0;
}
+bool eDVBFrontend::isScheduledSendDiseqc()
+{
+ bool has_senddiseqc = false;
+ if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
+ {
+ eSecCommandList::iterator cur = m_sec_sequence.current();
+ while(cur != m_sec_sequence.end())
+ {
+ if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
+ {
+ has_senddiseqc = true;
+ break;
+ }
+ }
+ }
+ return has_senddiseqc;
+}
+
RESULT eDVBFrontend::getData(int num, long &data)
{
if ( num < NUM_DATA_ENTRIES )
int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
{
int type;
- if (feparm->getSystem(type) || type != m_type || !m_enabled)
+ int score = 0;
+ bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
+
+ if (feparm->getSystem(type) || !m_enabled)
return 0;
- if (m_type == eDVBFrontend::feSatellite)
+
+ if (type == eDVBFrontend::feSatellite)
{
- ASSERT(m_sec);
eDVBFrontendParametersSatellite sat_parm;
- int ret = feparm->getDVBS(sat_parm);
- ASSERT(!ret);
- if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
+ bool can_handle_dvbs, can_handle_dvbs2;
+ can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
+ can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
+ if (feparm->getDVBS(sat_parm) < 0)
+ {
+ return 0;
+ }
+ if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
+ {
+ return 0;
+ }
+ if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
+ {
+ return 0;
+ }
+ score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
+ if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
+ {
+ /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
+ score--;
+ }
+ }
+
+ else if (type == eDVBFrontend::feCable)
+ {
+ eDVBFrontendParametersCable cab_parm;
+ if (feparm->getDVBC(cab_parm) < 0)
+ {
+ return 0;
+ }
+#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
+ if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
+ {
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;
+ }
+#else
+ if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
+ {
+ return 0;
+ }
+#endif
+ score = 2;
}
- else if (m_type == eDVBFrontend::feCable)
- return 2; // more prio for cable frontends
- else if (m_type == eDVBFrontend::feTerrestrial)
+
+ else if (type == eDVBFrontend::feTerrestrial)
{
eDVBFrontendParametersTerrestrial ter_parm;
- if ( feparm->getDVBT(ter_parm) )
+ bool can_handle_dvbt, can_handle_dvbt2;
+ can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
+ can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
+ if (feparm->getDVBT(ter_parm) < 0)
+ {
+ return 0;
+ }
+ if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
{
return 0;
}
- if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
+ if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !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 && 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::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
+{
+ std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
+ if (it != m_delsys.end() && it->second)
+ {
+ if (obeywhitelist && !m_delsys_whitelist.empty())
+ {
+ it = m_delsys_whitelist.find(sys);
+ if (it == m_delsys_whitelist.end() || !it->second) return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
+{
+ m_delsys_whitelist.clear();
+ for (unsigned int i = 0; i < whitelist.size(); i++)
+ {
+ m_delsys_whitelist[whitelist[i]] = true;
+ }
+ if (m_simulate_fe)
+ {
+ m_simulate_fe->setDeliverySystemWhitelist(whitelist);
+ }
}
bool eDVBFrontend::setSlotInfo(ePyObject obj)
// m_slotid, m_description);
return false;
}
- m_enabled = Enabled == Py_True;
+ m_enabled = (Enabled == Py_True);
// HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
!!strstr(m_description, "Alps BSBE2") ||
!!strstr(m_description, "Alps -S") ||
!!strstr(m_description, "BCM4501");
- m_can_handle_dvbs2 = IsDVBS2 == Py_True;
- m_can_handle_dvbt2 = IsDVBT2 == Py_True;
+ if (IsDVBS2 == Py_True)
+ {
+ /* HACK for legacy dvb api without DELSYS support */
+ m_delsys[SYS_DVBS2] = true;
+ }
+ if (IsDVBT2 == Py_True)
+ {
+ /* HACK for legacy dvb api without DELSYS support */
+ m_delsys[SYS_DVBT2] = 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" );
+ m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", Enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No" );
return true;
arg_error:
PyErr_SetString(PyExc_StandardError,