#include <lib/dvb/dvb.h>
#include <lib/base/eerror.h>
+#include <lib/base/nconfig.h> // access to python config
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
return 0;
}
-RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff) const
+RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
{
if (!parm)
return -1;
diff = 1<<29;
else if (sat.polarisation != osat.polarisation)
diff = 1<<28;
+ else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC::fAuto && osat.fec != eDVBFrontendParametersSatellite::FEC::fAuto)
+ diff = 1<<27;
+ else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation::Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation::Auto)
+ diff = 1<<27;
else
{
diff = abs(sat.frequency - osat.frequency);
if (parm->getDVBC(ocable))
return -2;
- if (cable.modulation != ocable.modulation && cable.modulation != eDVBFrontendParametersCable::Modulation::Auto && ocable.modulation != eDVBFrontendParametersCable::Modulation::Auto)
+ if (exact && cable.modulation != ocable.modulation
+ && cable.modulation != eDVBFrontendParametersCable::Modulation::Auto
+ && ocable.modulation != eDVBFrontendParametersCable::Modulation::Auto)
diff = 1 << 29;
- else if (cable.inversion != ocable.inversion && cable.inversion != eDVBFrontendParametersCable::Inversion::Unknown && ocable.inversion != eDVBFrontendParametersCable::Inversion::Unknown)
- diff = 1 << 28;
+ else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC::fAuto && ocable.fec_inner != eDVBFrontendParametersCable::FEC::fAuto)
+ diff = 1 << 27;
else
{
diff = abs(cable.frequency - ocable.frequency);
diff += abs(cable.symbol_rate - ocable.symbol_rate);
}
-
return 0;
case iDVBFrontend::feTerrestrial:
eDVBFrontendParametersTerrestrial oterrestrial;
if (parm->getDVBT(oterrestrial))
return -2;
- diff = abs(terrestrial.frequency - oterrestrial.frequency);
+ if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
+ oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto &&
+ terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto)
+ diff = 1 << 30;
+ else if (exact && oterrestrial.modulation != terrestrial.modulation &&
+ oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation::Auto &&
+ terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation::Auto)
+ diff = 1 << 30;
+ else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
+ oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto &&
+ terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto)
+ diff = 1 << 30;
+ else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
+ oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto &&
+ terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto)
+ diff = 1 << 30;
+ else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
+ oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy::HAuto &&
+ terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy::HAuto)
+ diff = 1 << 30;
+ else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
+ oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC::fAuto &&
+ terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC::fAuto)
+ diff = 1 << 30;
+ else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
+ oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC::fAuto &&
+ terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC::fAuto)
+ diff = 1 << 30;
+ else
+ diff = abs(terrestrial.frequency - oterrestrial.frequency);
return 0;
default:
return -1;
return 0;
}
-void PutToDict(PyObject *dict, const char*key, long value)
+void PutToDict(ePyObject &dict, const char*key, long value)
{
- PyObject *item = PyInt_FromLong(value);
+ ePyObject item = PyInt_FromLong(value);
if (item)
{
if (PyDict_SetItemString(dict, key, item))
eDebug("could not create PyObject for %s", key);
}
-void PutToDict(PyObject *dict, const char*key, const char *value)
+void PutToDict(ePyObject &dict, const char*key, const char *value)
{
- PyObject *item = PyString_FromString(value);
+ ePyObject item = PyString_FromString(value);
if (item)
{
if (PyDict_SetItemString(dict, key, item))
eDebug("could not create PyObject for %s", key);
}
-void fillDictWithSatelliteData(PyObject *dict, const FRONTENDPARAMETERS &parm, eDVBFrontend *fe)
+void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, eDVBFrontend *fe)
{
int freq_offset=0;
int csw=0;
PutToDict(dict, "system", tmp);
}
-void fillDictWithCableData(PyObject *dict, const FRONTENDPARAMETERS &parm)
+void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
{
const char *tmp=0;
PutToDict(dict, "frequency", parm_frequency/1000);
PutToDict(dict, "modulation", tmp);
}
-void fillDictWithTerrestrialData(PyObject *dict, const FRONTENDPARAMETERS &parm)
+void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
{
const char *tmp=0;
PutToDict(dict, "frequency", parm_frequency);
PyObject *eDVBFrontend::readTransponderData(bool original)
{
- PyObject *ret=PyDict_New();
+ ePyObject ret=PyDict_New();
if (ret)
{
}
}
else
- {
- Py_INCREF(Py_None);
- ret = Py_None;
- }
+ Py_RETURN_NONE;
+
return ret;
}
case eSecCommand::IF_VOLTAGE_GOTO:
{
eSecCommand::pair &compare = m_sec_sequence.current()->compare;
- if ( compare.voltage == m_curVoltage && setSecSequencePos(compare.steps) )
+ if ( compare.voltage == m_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
break;
++m_sec_sequence.current();
break;
case eSecCommand::IF_NOT_VOLTAGE_GOTO:
{
eSecCommand::pair &compare = m_sec_sequence.current()->compare;
- if ( compare.voltage != m_curVoltage && setSecSequencePos(compare.steps) )
+ if ( compare.voltage != m_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
+ break;
+ ++m_sec_sequence.current();
+ break;
+ }
+ case eSecCommand::IF_TONE_GOTO:
+ {
+ eSecCommand::pair &compare = m_sec_sequence.current()->compare;
+ if ( compare.tone == m_data[CUR_TONE] && setSecSequencePos(compare.steps) )
+ break;
+ ++m_sec_sequence.current();
+ break;
+ }
+ case eSecCommand::IF_NOT_TONE_GOTO:
+ {
+ eSecCommand::pair &compare = m_sec_sequence.current()->compare;
+ if ( compare.tone != m_data[CUR_TONE] && setSecSequencePos(compare.steps) )
break;
++m_sec_sequence.current();
break;
case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
{
eSecCommand::pair &compare = m_sec_sequence.current()->compare;
- int idx = compare.voltage;
+ int idx = compare.val;
if ( idx == 0 || idx == 1 )
{
int idle = readInputpower();
break;
case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
{
- int idleInputpower = m_idleInputpower[ (m_curVoltage&1) ? 0 : 1];
+ int idleInputpower = m_idleInputpower[ (m_data[CUR_VOLTAGE]&1) ? 0 : 1];
eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
const char *txt = cmd.direction ? "running" : "stopped";
eDebug("[SEC] waiting for rotor %s %d, idle %d, delta %d",
break;
}
default:
+ eDebug("[SEC] unhandled sec command %d",
+ ++m_sec_sequence.current()->cmd);
++m_sec_sequence.current();
- eDebug("[SEC] unhandled sec command");
}
m_tuneTimer->start(delay,true);
}
res = m_sec->prepare(*this, parm, feparm, 1 << m_fe);
if (!res)
{
- eDebug("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d",
+ eDebug("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
feparm.system,
feparm.frequency,
feparm.polarisation,
feparm.symbol_rate,
feparm.inversion,
- feparm.fec);
+ feparm.fec,
+ feparm.orbital_position);
parm_u_qpsk_symbol_rate = feparm.symbol_rate;
switch (feparm.inversion)
{
parm_u_qam_fec_inner = FEC_AUTO;
break;
}
+ eDebug("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
+ parm_frequency/1000,
+ parm_u_qam_symbol_rate,
+ parm_u_qam_fec_inner,
+ parm_u_qam_modulation,
+ parm_inversion);
return 0;
}
if (!m_sn)
{
eDebug("no frontend device opened... do not try to tune !!!");
- return -ENODEV;
+ res = -ENODEV;
+ goto tune_error;
}
if (m_type == -1)
- return -ENODEV;
+ {
+ res = -ENODEV;
+ goto tune_error;
+ }
m_sn->stop();
m_sec_sequence.clear();
if (where.getDVBS(feparm))
{
eDebug("no dvbs data!");
- return -EINVAL;
+ res = -EINVAL;
+ goto tune_error;
}
- res=prepare_sat(feparm);
m_sec->setRotorMoving(false);
+ res=prepare_sat(feparm);
+ if (res)
+ goto tune_error;
+
break;
}
case feCable:
{
eDVBFrontendParametersCable feparm;
if (where.getDVBC(feparm))
- return -EINVAL;
- res=prepare_cable(feparm);
- if (!res)
{
- m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT) );
- m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ res = -EINVAL;
+ goto tune_error;
}
+ res=prepare_cable(feparm);
+ if (res)
+ goto tune_error;
+
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT) );
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
break;
}
case feTerrestrial:
if (where.getDVBT(feparm))
{
eDebug("no -T data");
- return -EINVAL;
+ res = -EINVAL;
+ goto tune_error;
}
res=prepare_terrestrial(feparm);
- if (!res)
- {
- m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT) );
- m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
- }
+ if (res)
+ goto tune_error;
+
+ std::string enable_5V;
+ char configStr[255];
+ snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_fe);
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT) );
+ ePythonConfigQuery::getConfigValue(configStr, enable_5V);
+ if (enable_5V == "True")
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
+ else
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+
break;
}
}
- if (!res) // prepare ok
- {
- m_tuneTimer->start(0,true);
- m_sec_sequence.current() = m_sec_sequence.begin();
+ m_tuneTimer->start(0,true);
+ m_sec_sequence.current() = m_sec_sequence.begin();
- if (m_state != stateTuning)
- {
- m_tuning = 1;
- m_state = stateTuning;
- m_stateChanged(this);
- }
+ if (m_state != stateTuning)
+ {
+ m_tuning = 1;
+ m_state = stateTuning;
+ m_stateChanged(this);
}
return res;
+
+tune_error:
+ m_tuneTimer->stop();
+ return res;
}
RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
RESULT eDVBFrontend::setVoltage(int voltage)
{
- if (m_type != feSatellite)
+ if (m_type == feCable)
return -1;
#if HAVE_DVB_API_VERSION < 3
secVoltage vlt;
bool increased=false;
fe_sec_voltage_t vlt;
#endif
- m_curVoltage=voltage;
+ m_data[CUR_VOLTAGE]=voltage;
switch (voltage)
{
case voltageOff:
#if HAVE_DVB_API_VERSION < 3
return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
#else
- if (::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
+ if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
#endif
#else
fe_sec_tone_mode_t tone;
#endif
-
+ m_data[CUR_TONE]=t;
switch (t)
{
case toneOn:
{
ASSERT(m_sec);
eDVBFrontendParametersSatellite sat_parm;
- ASSERT(!feparm->getDVBS(sat_parm));
+ int ret = feparm->getDVBS(sat_parm);
+ ASSERT(!ret);
return m_sec->canTune(sat_parm, this, 1 << m_fe);
}
+ else if (m_type == eDVBFrontend::feCable)
+ return 2; // more prio for cable frontends
return 1;
}