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_need_rotor_workaround(false), m_can_handle_dvbs2(false)
+ ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false)
,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
#if HAVE_DVB_API_VERSION < 3
,m_secfd(-1)
closeFrontend();
}
+void eDVBFrontend::reopenFrontend()
+{
+ sleep(1);
+ m_type = -1;
+ openFrontend();
+}
+
int eDVBFrontend::openFrontend()
{
if (m_state != stateClosed)
return 0;
}
-int eDVBFrontend::closeFrontend(bool force)
+int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
{
if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
{
eDebugNoSimulate("close frontend %d", m_dvbid);
if (m_data[SATCR] != -1)
{
- turnOffSatCR(m_data[SATCR]);
+ if (!no_delayed)
+ {
+ m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
+ m_tuneTimer->start(0, true);
+ if(!m_tuneTimer->isActive())
+ {
+ int timeout=0;
+ eDebug("[turnOffSatCR] no mainloop");
+ while(true)
+ {
+ timeout = tuneLoopInt();
+ if (timeout == -1)
+ break;
+ usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
+ }
+ }
+ else
+ eDebug("[turnOffSatCR] running mainloop");
+ return 0;
+ }
+ else
+ m_data[ROTOR_CMD] = -1;
}
+
setTone(iDVBFrontend::toneOff);
setVoltage(iDVBFrontend::voltageOff);
m_tuneTimer->stop();
+
if (m_sec && !m_simulate)
- m_sec->setRotorMoving(false);
+ m_sec->setRotorMoving(m_slotid, false);
if (!::close(m_fd))
m_fd=-1;
else
{
eDebug("stateLostLock");
state = stateLostLock;
- sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
+ if (!m_rotor_mode)
+ sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
}
}
if (m_state != state)
float fval1 = SDS_SNRE / 268435456.0,
fval2, fval3, fval4;
- if (parm_u_qpsk_fec_inner <= FEC_S2_QPSK_9_10) // DVB-S2 QPSK
+ if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
{
fval2 = 6.76;
fval3 = 4.35;
}
else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
ret = (snr * 100) >> 8;
+ else if (!strcmp(m_description, "CXD1981"))
+ {
+ int mse = (~snr) & 0xFF;
+ switch (parm_u_qam_modulation) {
+ case QAM_16:
+ case QAM_64:
+ case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
+ case QAM_32:
+ case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
+
+ default: break;
+ }
+ }
if (type == signalQuality)
{
case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
}
+ PutToDict(dict, "fec_inner", tmp);
switch (p[0].u.data)
{
PutToDict(dict, "orbital_position", orb_pos);
PutToDict(dict, "polarization", polarization);
- switch(parm_u_qpsk_fec_inner)
+ switch((int)parm_u_qpsk_fec_inner)
{
case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
return 0;
int power=m_slotid; // this is needed for read inputpower from the correct tuner !
char proc_name[64];
- sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid);
- FILE *f=fopen(proc_name, "r");
- if (f)
+ char proc_name2[64];
+ sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
+ sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
+ FILE *f;
+ if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
{
if (fscanf(f, "%d", &power) != 1)
eDebug("read %s failed!! (%m)", proc_name);
return true;
}
-void eDVBFrontend::tuneLoop() // called by m_tuneTimer
+void eDVBFrontend::tuneLoop()
+{
+ tuneLoopInt();
+}
+
+int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
{
- int delay=0;
+ int delay=-1;
eDVBFrontend *sec_fe = this;
eDVBRegisteredFrontend *regFE = 0;
long tmp = m_data[LINKED_PREV_PTR];
{
long *sec_fe_data = sec_fe->m_data;
// eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
+ delay = 0;
switch (m_sec_sequence.current()->cmd)
{
case eSecCommand::SLEEP:
break;
case eSecCommand::SET_ROTOR_MOVING:
if (!m_simulate)
- m_sec->setRotorMoving(true);
+ m_sec->setRotorMoving(m_slotid, true);
++m_sec_sequence.current();
break;
case eSecCommand::SET_ROTOR_STOPPED:
if (!m_simulate)
- m_sec->setRotorMoving(false);
+ m_sec->setRotorMoving(m_slotid, false);
++m_sec_sequence.current();
break;
case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
++m_sec_sequence.current();
break;
}
+ case eSecCommand::DELAYED_CLOSE_FRONTEND:
+ {
+ eDebugNoSimulate("[SEC] delayed close frontend");
+ closeFrontend(false, true);
+ ++m_sec_sequence.current();
+ break;
+ }
default:
eDebugNoSimulate("[SEC] unhandled sec command %d",
++m_sec_sequence.current()->cmd);
regFE->dec_use();
if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
tuneLoop();
+ return delay;
}
void eDVBFrontend::setFrontend(bool recvEvents)
res = -EINVAL;
goto tune_error;
}
+ if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
+ {
+ eDVBFrontend *sec_fe = this;
+ long tmp = m_data[LINKED_PREV_PTR];
+ while (tmp != -1)
+ {
+ eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
+ sec_fe = linked_fe->m_frontend;
+ sec_fe->getData(LINKED_NEXT_PTR, tmp);
+ }
+ eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
+ sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = sec_fe->m_data[ROTOR_CMD] = sec_fe->m_data[ROTOR_POS] = -1; // reset diseqc
+ }
+ m_rotor_mode = feparm.no_rotor_command_on_tune;
if (!m_simulate)
- m_sec->setRotorMoving(false);
+ m_sec->setRotorMoving(m_slotid, false);
res=prepare_sat(feparm, timeout);
if (res)
goto tune_error;
return 0;
}
-RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list)
+RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
{
- m_sec_sequence = list;
+ if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
+ m_sec_sequence.push_back(list);
+ else
+ m_sec_sequence = list;
return 0;
}
bool eDVBFrontend::setSlotInfo(ePyObject obj)
{
- ePyObject Id, Descr, Enabled, IsDVBS2;
- if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 4)
+ ePyObject Id, Descr, Enabled, IsDVBS2, frontendId;
+ if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5)
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);
- if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2))
+ frontendId = PyTuple_GET_ITEM(obj, 4);
+ m_slotid = PyInt_AsLong(Id);
+ if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId))
goto arg_error;
strcpy(m_description, PyString_AS_STRING(Descr));
- m_slotid = PyInt_AsLong(Id);
+ if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
+// eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
+// m_slotid, m_description);
+ return false;
+ }
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") ||
"eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
return false;
}
-
-RESULT eDVBFrontend::turnOffSatCR(int satcr)
-{
- eSecCommandList sec_sequence;
- // check if voltage is disabled
- eSecCommand::pair compare;
- compare.steps = +9; //nothing to do
- compare.voltage = iDVBFrontend::voltageOff;
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
-
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );
-
- eDVBDiseqcCommand diseqc;
- memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
- diseqc.len = 5;
- diseqc.data[0] = 0xE0;
- diseqc.data[1] = 0x10;
- diseqc.data[2] = 0x5A;
- diseqc.data[3] = satcr << 5;
- diseqc.data[4] = 0x00;
-
- sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50+20+14*diseqc.len) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
- setSecSequence(sec_sequence);
- return 0;
-}
-
-RESULT eDVBFrontend::ScanSatCR()
-{
- setFrontend();
- usleep(20000);
- setTone(iDVBFrontend::toneOff);
- return 0;
-}