From: Andreas Monzner Date: Tue, 6 Dec 2005 22:15:38 +0000 (+0000) Subject: ose no more used frontends and re-open on demand X-Git-Tag: 2.6.0~4812 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/7290c1872d4f6ac37c8090e1cc2e95aeddf6e814?hp=7aaa13924d6d60f6fb66a262ce6ecd8088aee9b6 ose no more used frontends and re-open on demand --- diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 8feb3c18..b1e8ad54 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -18,12 +18,12 @@ DEFINE_REF(eDVBAllocatedFrontend); eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe) { - m_fe->m_inuse++; + m_fe->inc_use(); } eDVBAllocatedFrontend::~eDVBAllocatedFrontend() { - --m_fe->m_inuse; + m_fe->dec_use(); } DEFINE_REF(eDVBAllocatedDemux); @@ -200,8 +200,6 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter) if (!adapter->getFrontend(frontend, i)) { - frontend->setTone(iDVBFrontend::toneOff); - frontend->setVoltage(iDVBFrontend::voltageOff); frontend->setSEC(m_sec); m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter)); } diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index ac5946cd..71c6a6c1 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -1,6 +1,7 @@ #ifndef __dvb_dvb_h #define __dvb_dvb_h +#include #include #include #include @@ -14,14 +15,35 @@ class eDVBChannel; (and how to deallocate it). */ class iDVBAdapter; -class eDVBRegisteredFrontend: public iObject +class eDVBRegisteredFrontend: public iObject, public Object { -DECLARE_REF(eDVBRegisteredFrontend); + DECLARE_REF(eDVBRegisteredFrontend); + eTimer *disable; + void closeFrontend() + { + if (!m_inuse) + m_frontend->closeFrontend(); + } public: + eDVBRegisteredFrontend(eDVBFrontend *fe, iDVBAdapter *adap) + :disable(new eTimer(eApp)), m_adapter(adap), m_frontend(fe), m_inuse(0) + { + disable = new eTimer(eApp); + CONNECT(disable->timeout, eDVBRegisteredFrontend::closeFrontend); + } + void dec_use() + { + if (!--m_inuse) + disable->start(3000, true); + } + void inc_use() + { + if (++m_inuse == 1) + m_frontend->openFrontend(); + } iDVBAdapter *m_adapter; ePtr m_frontend; int m_inuse; - eDVBRegisteredFrontend(eDVBFrontend *fe, iDVBAdapter *adap): m_adapter(adap), m_frontend(fe), m_inuse(0) { } }; struct eDVBRegisteredDemux diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index a26f6bd8..1cafcec4 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -208,102 +208,149 @@ RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const DEFINE_REF(eDVBFrontend); -eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): m_type(-1), m_fe(fe), m_curVoltage(-1) +eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok) + :m_type(-1), m_fe(fe), m_timeout(0), m_tuneTimer(0), m_fd(-1) +#if HAVE_DVB_API_VERSION < 3 + ,m_secfd(-1) +#endif { #if HAVE_DVB_API_VERSION < 3 - char sec_filename[128]; + sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe); #endif - char filename[128]; + sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe); + + m_timeout = new eTimer(eApp); + CONNECT(m_timeout->timeout, eDVBFrontend::timeout); + + m_tuneTimer = new eTimer(eApp); + CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop); + + int entries = sizeof(m_data) / sizeof(int); + for (int i=0; i= 0) + return -1; // already opened - m_sn = 0; - m_timeout = 0; + m_state=0; + m_curVoltage=voltageOff; + m_tuning=0; #if HAVE_DVB_API_VERSION < 3 - sprintf(sec_filename, "/dev/dvb/card%d/sec%d", adap, fe); - m_secfd = ::open(sec_filename, O_RDWR); + m_secfd = ::open(m_sec_filename, O_RDWR); if (m_secfd < 0) { - eWarning("failed! (%s) %m", sec_filename); - ok = 0; - return; + eWarning("failed! (%s) %m", m_sec_filename); + return -1; } FrontendInfo fe_info; - sprintf(filename, "/dev/dvb/card%d/frontend%d", adap, fe); #else - dvb_frontend_info fe_info; - sprintf(filename, "/dev/dvb/adapter%d/frontend%d", adap, fe); + dvb_frontend_info fe_info; #endif - eDebug("opening frontend."); - m_fd = ::open(filename, O_RDWR|O_NONBLOCK); + eDebug("opening frontend %d", m_fe); + m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK); if (m_fd < 0) { - eWarning("failed! (%s) %m", filename); - ok = 0; - return; - } - - result = ::ioctl(m_fd, FE_GET_INFO, &fe_info); - - if (result < 0) { - eWarning("ioctl FE_GET_INFO failed"); - ::close(m_fd); - m_fd = -1; - ok = 0; - return; + eWarning("failed! (%s) %m", m_filename); +#if HAVE_DVB_API_VERSION < 3 + ::close(m_secfd); + m_secfd=-1; +#endif + return -1; } - switch (fe_info.type) + if (m_type == -1) { - case FE_QPSK: - m_type = feSatellite; - break; - case FE_QAM: - m_type = feCable; - break; - case FE_OFDM: - m_type = feTerrestrial; - break; - default: - eWarning("unknown frontend type."); - ::close(m_fd); - m_fd = -1; - ok = 0; - return; + if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0) + { + 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; + } + + 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; +#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); } - eDebug("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10); - ok = 1; + + setTone(iDVBFrontend::toneOff); + setVoltage(iDVBFrontend::voltageOff); m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Read); CONNECT(m_sn->activated, eDVBFrontend::feEvent); m_sn->start(); - m_timeout = new eTimer(eApp); - CONNECT(m_timeout->timeout, eDVBFrontend::timeout); - - m_tuneTimer = new eTimer(eApp); - CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop); - - int entries = sizeof(m_data) / sizeof(int); - for (int i=0; im_inuse) + { + eDebug("dont close frontend %d until the linked frontend %d is still in use", + m_fe, linked_fe->m_frontend->getID()); + return; + } + } + eDebug("close frontend %d", m_fe); + if (m_fd >= 0) + { + ::close(m_fd); + m_fd=-1; + } +#if HAVE_DVB_API_VERSION < 3 + if (m_secfd >= 0) + { + ::close(m_secfd); + m_secfd=-1; + } +#endif + delete m_sn; + m_sn=0; - return; + setTone(iDVBFrontend::toneOff); + setVoltage(iDVBFrontend::voltageOff); } eDVBFrontend::~eDVBFrontend() { - if (m_fd >= 0) - ::close(m_fd); - if (m_sn) - delete m_sn; - if (m_timeout) - delete m_timeout; + closeFrontend(); + delete m_timeout; + delete m_tuneTimer; } void eDVBFrontend::feEvent(int w) @@ -609,7 +656,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer void eDVBFrontend::setFrontend() { - eDebug("setting frontend..\n"); + eDebug("setting frontend %d", m_fe); if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) { perror("FE_SET_FRONTEND failed"); @@ -684,7 +731,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) parm.frequency = feparm.frequency * 1000; parm.u.qam.symbol_rate = feparm.symbol_rate; #endif - fe_modulation_t mod; + fe_modulation_t mod=QAM_AUTO; switch (feparm.modulation) { case eDVBFrontendParametersCable::Modulation::QAM16: @@ -739,7 +786,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) break; } - fe_code_rate_t fec_inner; + fe_code_rate_t fec_inner=FEC_AUTO; switch (feparm.fec_inner) { case eDVBFrontendParametersCable::FEC::fNone: @@ -907,6 +954,8 @@ RESULT eDVBFrontend::connectStateChange(const Slot1 &stateCh RESULT eDVBFrontend::setVoltage(int voltage) { + if (m_type != feSatellite) + return -1; #if HAVE_DVB_API_VERSION < 3 secVoltage vlt; #else @@ -917,6 +966,8 @@ RESULT eDVBFrontend::setVoltage(int voltage) switch (voltage) { case voltageOff: + for (int i=0; i < 3; ++i) // reset diseqc + m_data[i]=-1; vlt = SEC_VOLTAGE_OFF; break; case voltage13: @@ -943,6 +994,8 @@ RESULT eDVBFrontend::getState(int &state) RESULT eDVBFrontend::setTone(int t) { + if (m_type != feSatellite) + return -1; #if HAVE_DVB_API_VERSION < 3 secToneMode_t tone; #else diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h index 8da0829c..7862e2ea 100644 --- a/lib/dvb/frontend.h +++ b/lib/dvb/frontend.h @@ -40,9 +40,12 @@ class eDVBFrontend: public iDVBFrontend, public Object int m_type; int m_fe; int m_fd; + char m_filename[128]; #if HAVE_DVB_API_VERSION < 3 int m_secfd; + char m_secfilename[128]; #endif + FRONTENDPARAMETERS parm; int m_state; Signal1 m_stateChanged; @@ -93,10 +96,11 @@ public: RESULT setData(int num, int val); int readFrontendData(int type); // bitErrorRate, signalPower, signalQuality - int isCompatibleWith(ePtr &feparm); - int getID() { return m_fe; } + + int openFrontend(); + void closeFrontend(); }; #endif diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index 4842945c..ab5d6397 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -163,27 +163,17 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite if (linked_to != -1) // check for linked tuners.. { - bool found=false; - eSmartPtrList::iterator it(m_avail_frontends.begin()); - for (; it != m_avail_frontends.end(); ++it) - if ( !linked_to ) - { - found=true; - break; - } - else - --linked_to; - - if (found && it->m_inuse) + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_to; + if (linked_fe->m_inuse) { int ocsw = -1, oucsw = -1, oToneburst = -1, oRotorPos = -1; - it->m_frontend->getData(0, ocsw); - it->m_frontend->getData(1, oucsw); - it->m_frontend->getData(2, oToneburst); - it->m_frontend->getData(6, oRotorPos); + linked_fe->m_frontend->getData(0, ocsw); + linked_fe->m_frontend->getData(1, oucsw); + linked_fe->m_frontend->getData(2, oToneburst); + linked_fe->m_frontend->getData(6, oRotorPos); #if 0 eDebug("compare csw %02x == lcsw %02x", csw, ocsw); @@ -251,19 +241,10 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA if (linked_to != -1) { - bool found=false; - eSmartPtrList::iterator it(m_avail_frontends.begin()); - for (; it != m_avail_frontends.end(); ++it) - if ( !linked_to ) - { - found=true; - break; - } - else - --linked_to; - if (found && it->m_inuse) + eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_to; + if (linked_fe->m_inuse) { - eDebug("[SEC] frontend is linked with another one and the other is in use.. so we dont do SEC!!"); + eDebug("[SEC] frontend is linked with another and the other one is in use.. so we dont do SEC!!"); linked=true; } } @@ -911,27 +892,20 @@ RESULT eDVBSatelliteEquipmentControl::setTunerLinked(int tu1, int tu2) if (tu1 == tu2) return -1; - eDVBFrontend *p1=NULL, *p2=NULL; - int tmp1=tu1, tmp2=tu2; + eDVBRegisteredFrontend *p1=NULL, *p2=NULL; - for (eSmartPtrList::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it) + int cnt=0; + for (eSmartPtrList::iterator it(m_avail_frontends.begin()); it != m_avail_frontends.end(); ++it, ++cnt) { - if ( !tmp1 ) - p1 = it->m_frontend; - else - --tmp1; - if (!tmp2) - p2 = it->m_frontend; - else - --tmp2; + if (cnt == tu1) + p1 = *it; + else if (cnt == tu2) + p2 = *it; } if (p1 && p2) { - p1->setData(7, tu2); - p1->setTone(iDVBFrontend::toneOff); - p1->setVoltage(iDVBFrontend::voltageOff); - - p2->setData(7, tu1); + p1->m_frontend->setData(7, (int)p2); // this is evil.. + p2->m_frontend->setData(7, (int)p1); return 0; } return -1;