X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/b2eebd0fef155a40a8a74468c4488cfb0c656a9a..a22c31de792a36f645c9c91d954e9d8e30f82064:/lib/dvb/frontend.cpp diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index b6e5e8ab..8b214130 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -383,8 +383,8 @@ RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const DEFINE_REF(eDVBFrontend); eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok) - :m_type(-1), m_dvbid(fe), m_slotid(fe), m_need_rotor_workaround(false) - ,m_fd(-1), m_sn(0), m_timeout(0), m_tuneTimer(0) + :m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe) + ,m_fd(-1), m_need_rotor_workaround(false), m_sn(0), m_timeout(0), m_tuneTimer(0) #if HAVE_DVB_API_VERSION < 3 ,m_secfd(-1) #endif @@ -419,17 +419,6 @@ int eDVBFrontend::openFrontend() m_tuning=0; #if HAVE_DVB_API_VERSION < 3 - if (m_secfd < 0) - { - m_secfd = ::open(m_sec_filename, O_RDWR); - if (m_secfd < 0) - { - eWarning("failed! (%s) %m", m_sec_filename); - return -1; - } - } - else - eWarning("sec %d already opened", m_dvbid); FrontendInfo fe_info; #else dvb_frontend_info fe_info; @@ -441,10 +430,6 @@ int eDVBFrontend::openFrontend() if (m_fd < 0) { eWarning("failed! (%s) %m", m_filename); -#if HAVE_DVB_API_VERSION < 3 - ::close(m_secfd); - m_secfd=-1; -#endif return -1; } } @@ -457,10 +442,6 @@ int eDVBFrontend::openFrontend() eWarning("ioctl FE_GET_INFO failed"); ::close(m_fd); m_fd = -1; -#if HAVE_DVB_API_VERSION < 3 - ::close(m_secfd); - m_secfd=-1; -#endif return -1; } @@ -479,15 +460,30 @@ int eDVBFrontend::openFrontend() eWarning("unknown frontend type."); ::close(m_fd); m_fd = -1; -#if HAVE_DVB_API_VERSION < 3 - ::close(m_secfd); - m_secfd=-1; -#endif return -1; } eDebug("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) + { + 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); + } +#endif + setTone(iDVBFrontend::toneOff); setVoltage(iDVBFrontend::voltageOff); @@ -631,36 +627,50 @@ int eDVBFrontend::readFrontendData(int type) uint16_t snr=0; if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE) eDebug("FE_READ_SNR failed (%m)"); - unsigned int SDS_SNRE = snr << 16; - - static float SNR_COEFF[6] = { - 100.0 / 4194304.0, - -7136.0 / 4194304.0, - 197418.0 / 4194304.0, - -2602183.0 / 4194304.0, - 20377212.0 / 4194304.0, - -37791203.0 / 4194304.0, - }; + if (!strcmp(m_description, "BCM4501 (internal)")) + { + unsigned int SDS_SNRE = snr << 16; + + static float SNR_COEFF[6] = { + 100.0 / 4194304.0, + -7136.0 / 4194304.0, + 197418.0 / 4194304.0, + -2602183.0 / 4194304.0, + 20377212.0 / 4194304.0, + -37791203.0 / 4194304.0, + }; - float fval1, fval2, snr_in_db; - int i; - fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)); - fval2 = pow(10.0, fval1)-1; - fval1 = 10.0 * log10(fval2); + float fval1, fval2, snr_in_db; + int i; + fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)); + fval2 = pow(10.0, fval1)-1; + fval1 = 10.0 * log10(fval2); - if (fval1 < 10.0) - { - fval2 = SNR_COEFF[0]; - for (i=0; i<6; ++i) + if (fval1 < 10.0) { - fval2 *= fval1; - fval2 += SNR_COEFF[i]; + fval2 = SNR_COEFF[0]; + for (i=0; i<6; ++i) + { + fval2 *= fval1; + fval2 += SNR_COEFF[i]; + } + fval1 = fval2; } - fval1 = fval2; - } - snr_in_db = fval1; + snr_in_db = fval1; - return (int)(snr_in_db * 100.0); + return (int)(snr_in_db * 100.0); + } + else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299 + !strcmp(m_description, "Alps -S") || + !strcmp(m_description, "Philips -S") || + !strcmp(m_description, "LG -S") ) + { + float snr_in_db=(snr-39075)/1764.7; + return (int)(snr_in_db * 100.0); + } + else + eDebug("no SNR dB caluclation for frontendtype %s yet", m_description); + return 0x12345678; } case signalQuality: { @@ -710,6 +720,18 @@ void PutToDict(ePyObject &dict, const char*key, long value) eDebug("could not create PyObject for %s", key); } +void PutToDict(ePyObject &dict, const char*key, ePyObject item) +{ + if (item) + { + if (PyDict_SetItemString(dict, key, item)) + eDebug("put %s to dict failed", key); + Py_DECREF(item); + } + else + eDebug("invalid PyObject for %s", key); +} + void PutToDict(ePyObject &dict, const char*key, const char *value) { ePyObject item = PyString_FromString(value); @@ -1038,7 +1060,15 @@ void eDVBFrontend::getFrontendStatus(ePyObject dest) PutToDict(dest, "tuner_synced", readFrontendData(synced)); PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate)); PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower)); - PutToDict(dest, "tuner_signal_power_db", readFrontendData(signalPowerdB)); + int sigPowerdB = readFrontendData(signalPowerdB); + if (sigPowerdB == 0x12345678) // not support yet + { + ePyObject obj=Py_None; + Py_INCREF(obj); + PutToDict(dest, "tuner_signal_power_db", obj); + } + else + PutToDict(dest, "tuner_signal_power_db", sigPowerdB); PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality)); } } @@ -1164,6 +1194,35 @@ bool eDVBFrontend::setSecSequencePos(int steps) return true; } +void eDVBFrontend::setRotorData(int pos, int cmd) +{ + m_data[ROTOR_CMD] = cmd; + m_data[ROTOR_POS] = pos; + if ( m_data[SATPOS_DEPENDS_PTR] != -1 ) + { + eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) m_data[SATPOS_DEPENDS_PTR]; + satpos_depends_to_fe->m_frontend->m_data[ROTOR_CMD] = cmd; + satpos_depends_to_fe->m_frontend->m_data[ROTOR_POS] = pos; + } + else + { + eDVBRegisteredFrontend *next = (eDVBRegisteredFrontend *)m_data[LINKED_NEXT_PTR]; + while ( (int)next != -1 ) + { + next->m_frontend->m_data[ROTOR_CMD] = cmd; + next->m_frontend->m_data[ROTOR_POS] = pos; + next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[LINKED_NEXT_PTR]; + } + eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)m_data[LINKED_PREV_PTR]; + while ( (int)prev != -1 ) + { + prev->m_frontend->m_data[ROTOR_CMD] = cmd; + prev->m_frontend->m_data[ROTOR_POS] = pos; + prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[LINKED_PREV_PTR]; + } + } +} + void eDVBFrontend::tuneLoop() // called by m_tuneTimer { int delay=0; @@ -1359,14 +1418,13 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer ++m_sec_sequence.current(); break; case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS: - m_data[ROTOR_CMD] = m_data[ROTOR_POS] = -1; eDebug("[SEC] invalidate current rotorparams"); + setRotorData(-1,-1); ++m_sec_sequence.current(); break; case eSecCommand::UPDATE_CURRENT_ROTORPARAMS: - m_data[ROTOR_CMD] = m_data[NEW_ROTOR_CMD]; - m_data[ROTOR_POS] = m_data[NEW_ROTOR_POS]; - eDebug("[SEC] update current rotorparams %d %04x %d", m_timeoutCount, m_data[5], m_data[6]); + setRotorData(m_data[NEW_ROTOR_POS], m_data[NEW_ROTOR_CMD]); + eDebug("[SEC] update current rotorparams %d %04x %d", m_timeoutCount, m_data[ROTOR_CMD], m_data[ROTOR_POS]); ++m_sec_sequence.current(); break; case eSecCommand::SET_ROTOR_DISEQC_RETRYS: @@ -2061,7 +2119,7 @@ RESULT eDVBFrontend::setData(int num, int val) int eDVBFrontend::isCompatibleWith(ePtr &feparm) { int type; - if (feparm->getSystem(type) || type != m_type) + if (feparm->getSystem(type) || type != m_type || !m_enabled) return 0; if (m_type == eDVBFrontend::feSatellite) @@ -2077,25 +2135,26 @@ int eDVBFrontend::isCompatibleWith(ePtr &feparm) return 1; } -void eDVBFrontend::setSlotInfo(ePyObject obj) +bool eDVBFrontend::setSlotInfo(ePyObject obj) { - ePyObject Id, Descr; - if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) + ePyObject Id, Descr, Enabled; + if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 3) goto arg_error; Id = PyTuple_GET_ITEM(obj, 0); Descr = PyTuple_GET_ITEM(obj, 1); - if (!PyInt_Check(Id) || !PyString_Check(Descr)) + Enabled = PyTuple_GET_ITEM(obj, 2); + if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled)) goto arg_error; strcpy(m_description, PyString_AS_STRING(Descr)); m_slotid = PyInt_AsLong(Id); - + 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 -S"); - - eDebug("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s", - m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No"); - return; + eDebug("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s", + m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No" ); + return true; arg_error: PyErr_SetString(PyExc_StandardError, - "eDVBFrontend::setSlotInfo must get a tuple with first param slotid and second param slot description"); + "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean"); + return false; }