From 6696994da0d59a3b483eda65d1dc8b1a9df67cc0 Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Fri, 3 Oct 2008 11:41:25 +0000 Subject: [PATCH] add code to simulate recordings (with faked frontends) now its more easy to build a timer overlap detection or similar --- lib/dvb/dvb.cpp | 153 ++++++++++--- lib/dvb/dvb.h | 14 +- lib/dvb/frontend.cpp | 373 +++++++++++++++++++------------ lib/dvb/frontend.h | 4 +- lib/dvb/pmt.cpp | 71 +++--- lib/dvb/pmt.h | 2 +- lib/dvb/sec.cpp | 100 ++++++++- lib/dvb/sec.h | 4 +- lib/dvb_ci/dvbci.cpp | 4 +- lib/service/iservice.h | 2 +- lib/service/servicedvb.cpp | 2 + lib/service/servicedvbrecord.cpp | 15 +- lib/service/servicedvbrecord.h | 3 +- timer.py | 23 ++ 14 files changed, 533 insertions(+), 237 deletions(-) diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index f04dac0b..f163230e 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -65,7 +65,8 @@ eDVBResourceManager::eDVBResourceManager() { avail = 1; busy = 0; - m_sec = new eDVBSatelliteEquipmentControl(m_frontend); + m_sec = new eDVBSatelliteEquipmentControl(m_frontend, m_simulate_frontend); + if (!instance) instance = this; @@ -80,8 +81,8 @@ eDVBResourceManager::eDVBResourceManager() num_adapter++; } - eDebug("found %d adapter, %d frontends and %d demux", - m_adapter.size(), m_frontend.size(), m_demux.size()); + eDebug("found %d adapter, %d frontends(%d sim) and %d demux", + m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size()); eDVBCAService::registerChannelCallback(this); @@ -117,10 +118,18 @@ eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr) break; ePtr fe; - int ok = 0; - fe = new eDVBFrontend(m_nr, num_fe, ok); - if (ok) - m_frontend.push_back(fe); + { + int ok = 0; + fe = new eDVBFrontend(m_nr, num_fe, ok); + if (ok) + m_frontend.push_back(fe); + } + { + int ok = 0; + fe = new eDVBFrontend(m_nr, num_fe, ok, true); + if (ok) + m_simulate_frontend.push_back(fe); + } ++num_fe; } @@ -173,9 +182,9 @@ int eDVBAdapterLinux::getNumFrontends() return m_frontend.size(); } -RESULT eDVBAdapterLinux::getFrontend(ePtr &fe, int nr) +RESULT eDVBAdapterLinux::getFrontend(ePtr &fe, int nr, bool simulate) { - eSmartPtrList::iterator i(m_frontend.begin()); + eSmartPtrList::iterator i(simulate ? m_simulate_frontend.begin() : m_frontend.begin()); while (nr && (i != m_frontend.end())) { --nr; @@ -249,6 +258,32 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter) } } } + + prev_dvbt_frontend = 0; + for (i=0; i frontend; + if (!adapter->getFrontend(frontend, i, true)) + { + int frontendType=0; + frontend->getFrontendType(frontendType); + eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter); +// CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged); + m_simulate_frontend.push_back(new_fe); + frontend->setSEC(m_sec); + // we must link all dvb-t frontends ( for active antenna voltage ) + if (frontendType == iDVBFrontend::feTerrestrial) + { + if (prev_dvbt_frontend) + { + prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe); + frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend)); + } + prev_dvbt_frontend = new_fe; + } + } + } + } PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list) @@ -273,16 +308,24 @@ PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list) if (!i->m_frontend->setSlotInfo(obj)) return NULL; } + pos=0; + for (eSmartPtrList::iterator i(m_simulate_frontend.begin()); i != m_simulate_frontend.end(); ++i) + { + ePyObject obj = PyList_GET_ITEM(list, pos++); + if (!i->m_frontend->setSlotInfo(obj)) + return NULL; + } Py_RETURN_NONE; } -RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, ePtr &feparm) +RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, ePtr &feparm, bool simulate) { + eSmartPtrList &frontends = simulate ? m_simulate_frontend : m_frontend; ePtr best; int bestval = 0; int foundone = 0; - for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) + for (eSmartPtrList::iterator i(frontends.begin()); i != frontends.end(); ++i) { int c = i->m_frontend->isCompatibleWith(feparm); @@ -291,12 +334,15 @@ RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, eP if (!i->m_inuse) { +// eDebug("Slot %d, score %d", i->m_frontend->getSlotID(), c); if (c > bestval) { bestval = c; best = i; } } +// else +// eDebug("Slot %d, score %d... but BUSY!!!!!!!!!!!", i->m_frontend->getSlotID(), c); } if (best) @@ -467,11 +513,24 @@ RESULT eDVBResourceManager::getChannelList(ePtr &list) return -ENOENT; } -RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel) +#define eDebugNoSimulate(x...) \ + do { \ + if (!simulate) \ + eDebug(x); \ + } while(0) +// else \ +// { \ +// eDebugNoNewLine("SIMULATE:"); \ +// eDebug(x); \ +// } \ + + +RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate) { /* first, check if a channel is already existing. */ + std::list &active_channels = simulate ? m_active_simulate_channels : m_active_channels; - if (m_cached_channel) + if (!simulate && m_cached_channel) { eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel); if(channelid==cache_chan->getChannelID()) @@ -485,30 +544,30 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse m_releaseCachedChannelTimer.stop(); } -// eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get()); - for (std::list::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i) + eDebugNoSimulate("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get()); + for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { -// eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get()); + eDebugNoSimulate("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get()); if (i->m_channel_id == channelid) { -// eDebug("found shared channel.."); + eDebugNoSimulate("found shared channel.."); channel = i->m_channel; return 0; } } - + /* no currently available channel is tuned to this channelid. create a new one, if possible. */ if (!m_list) { - eDebug("no channel list set!"); + eDebugNoSimulate("no channel list set!"); return errNoChannelList; } ePtr feparm; if (m_list->getChannelFrontendData(channelid, feparm)) { - eDebug("channel not found!"); + eDebugNoSimulate("channel not found!"); return errChannelNotInList; } @@ -516,7 +575,7 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse ePtr fe; - int err = allocateFrontend(fe, feparm); + int err = allocateFrontend(fe, feparm, simulate); if (err) return err; @@ -530,9 +589,15 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse channel = 0; return errChidNotFound; } - m_cached_channel = channel = ch; - m_cached_channel_state_changed_conn = - CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged); + + if (simulate) + channel = ch; + else + { + m_cached_channel = channel = ch; + m_cached_channel_state_changed_conn = + CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged); + } return 0; } @@ -610,26 +675,42 @@ RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr &channel) RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch) { - m_active_channels.push_back(active_channel(chid, ch)); - /* emit */ m_channelAdded(ch); + ePtr fe; + if (!ch->getFrontend(fe)) + { + eDVBFrontend *frontend = (eDVBFrontend*)&(*fe); + if (frontend->is_simulate()) + m_active_simulate_channels.push_back(active_channel(chid, ch)); + else + { + m_active_channels.push_back(active_channel(chid, ch)); + /* emit */ m_channelAdded(ch); + } + } return 0; } RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch) { - int cnt = 0; - for (std::list::iterator i(m_active_channels.begin()); i != m_active_channels.end();) + ePtr fe; + if (!ch->getFrontend(fe)) { - if (i->m_channel == ch) + eDVBFrontend *frontend = (eDVBFrontend*)&(*fe); + std::list &active_channels = frontend->is_simulate() ? m_active_simulate_channels : m_active_channels; + int cnt = 0; + for (std::list::iterator i(active_channels.begin()); i != active_channels.end();) { - i = m_active_channels.erase(i); - ++cnt; - } else - ++i; + if (i->m_channel == ch) + { + i = active_channels.erase(i); + ++cnt; + } else + ++i; + } + ASSERT(cnt == 1); + if (cnt == 1) + return 0; } - ASSERT(cnt == 1); - if (cnt == 1) - return 0; return -ENOENT; } diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index 04543ae2..bceb9ad0 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -107,7 +107,7 @@ public: virtual RESULT getDemux(ePtr &demux, int nr) = 0; virtual int getNumFrontends() = 0; - virtual RESULT getFrontend(ePtr &fe, int nr) = 0; + virtual RESULT getFrontend(ePtr &fe, int nr, bool simulate=false) = 0; }; class eDVBAdapterLinux: public iDVBAdapter @@ -120,12 +120,12 @@ public: RESULT getDemux(ePtr &demux, int nr); int getNumFrontends(); - RESULT getFrontend(ePtr &fe, int nr); + RESULT getFrontend(ePtr &fe, int nr, bool simulate=false); static int exist(int nr); private: int m_nr; - eSmartPtrList m_frontend; + eSmartPtrList m_frontend, m_simulate_frontend; eSmartPtrList m_demux; }; #endif // SWIG @@ -138,7 +138,7 @@ class eDVBResourceManager: public iObject, public Object eSmartPtrList m_adapter; eSmartPtrList m_demux; - eSmartPtrList m_frontend; + eSmartPtrList m_frontend, m_simulate_frontend; void addAdapter(iDVBAdapter *adapter); struct active_channel @@ -150,7 +150,7 @@ class eDVBResourceManager: public iObject, public Object active_channel(const eDVBChannelID &chid, eDVBChannel *ch) : m_channel_id(chid), m_channel(ch) { } }; - std::list m_active_channels; + std::list m_active_channels, m_active_simulate_channels; ePtr m_list; ePtr m_sec; @@ -191,7 +191,7 @@ public: int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore); /* allocate channel... */ - RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel); + RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate=false); RESULT allocatePVRChannel(eUsePtr &channel); static RESULT getInstance(ePtr &); @@ -202,7 +202,7 @@ public: there might be a priority given to certain frontend/chid combinations. this will be evaluated here. */ - RESULT allocateFrontend(ePtr &fe, ePtr &feparm); + RESULT allocateFrontend(ePtr &fe, ePtr &feparm, bool simulate=false); RESULT allocateFrontendByIndex(ePtr &fe, int slot_index); /* allocate a demux able to filter on the selected frontend. */ diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index af627e26..8bfe4858 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -76,6 +76,28 @@ #include #include +#define eDebugNoSimulate(x...) \ + do { \ + if (!m_simulate) \ + eDebug(x); \ + } while(0) +// else \ +// { \ +// eDebugNoNewLine("SIMULATE:"); \ +// eDebug(x); \ +// } \ + +#define eDebugNoSimulateNoNewLine(x...) \ + do { \ + if (!m_simulate) \ + eDebugNoNewLine(x); \ + } while(0) +// else \ +// { \ +// eDebugNoNewLine("SIMULATE:"); \ +// eDebugNoNewLine(x); \ +// } \ + void eDVBDiseqcCommand::setCommandString(const char *str) { if (!str) @@ -323,7 +345,6 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters if (parm->getDVBT(oterrestrial)) return -2; - if (exact && oterrestrial.bandwidth != terrestrial.bandwidth && oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto && terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto) @@ -419,8 +440,8 @@ DEFINE_REF(eDVBFrontend); int eDVBFrontend::PriorityOrder=0; -eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok) - :m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe) +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_sn(0), m_timeout(0), m_tuneTimer(0) #if HAVE_DVB_API_VERSION < 3 @@ -433,6 +454,7 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok) #else sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe); #endif + m_timeout = new eTimer(eApp); CONNECT(m_timeout->timeout, eDVBFrontend::timeout); @@ -461,14 +483,17 @@ int eDVBFrontend::openFrontend() #else dvb_frontend_info fe_info; #endif - eDebug("opening frontend %d", m_dvbid); + eDebugNoSimulate("opening frontend %d", m_dvbid); if (m_fd < 0) { - m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK); - if (m_fd < 0) + if (!m_simulate || m_type == -1) { - eWarning("failed! (%s) %m", m_filename); - return -1; + m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK); + if (m_fd < 0) + { + eWarning("failed! (%s) %m", m_filename); + return -1; + } } } else @@ -500,7 +525,7 @@ int eDVBFrontend::openFrontend() m_fd = -1; return -1; } - eDebug("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10); + eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10); } #if HAVE_DVB_API_VERSION < 3 @@ -508,13 +533,16 @@ int eDVBFrontend::openFrontend() { if (m_secfd < 0) { - m_secfd = ::open(m_sec_filename, O_RDWR); - if (m_secfd < 0) + if (!m_simulate) { - eWarning("failed! (%s) %m", m_sec_filename); - ::close(m_fd); - m_fd=-1; - return -1; + 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 @@ -525,8 +553,11 @@ int eDVBFrontend::openFrontend() setTone(iDVBFrontend::toneOff); setVoltage(iDVBFrontend::voltageOff); - m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Read, false); - CONNECT(m_sn->activated, eDVBFrontend::feEvent); + if (!m_simulate) + { + m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Read, false); + CONNECT(m_sn->activated, eDVBFrontend::feEvent); + } return 0; } @@ -541,26 +572,32 @@ int eDVBFrontend::closeFrontend(bool force) eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp; if (linked_fe->m_inuse) { - eDebug("dont close frontend %d until the linked frontend %d in slot %d is still in use", + eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use", m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID()); return -1; } linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp); } } + if (m_fd >= 0) { - eDebug("close frontend %d", m_dvbid); - m_tuneTimer->stop(); + eDebugNoSimulate("close frontend %d", m_dvbid); setTone(iDVBFrontend::toneOff); setVoltage(iDVBFrontend::voltageOff); - if (m_sec) + m_tuneTimer->stop(); + if (m_sec && !m_simulate) m_sec->setRotorMoving(false); if (!::close(m_fd)) m_fd=-1; else eWarning("couldnt close frontend %d", m_dvbid); } + else if (m_simulate) + { + setTone(iDVBFrontend::toneOff); + setVoltage(iDVBFrontend::voltageOff); + } #if HAVE_DVB_API_VERSION < 3 if (m_secfd >= 0) { @@ -664,20 +701,28 @@ int eDVBFrontend::readFrontendData(int type) case bitErrorRate: { uint32_t ber=0; - if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE) - eDebug("FE_READ_BER failed (%m)"); + if (!m_simulate) + { + if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE) + eDebug("FE_READ_BER failed (%m)"); + } return ber; } case signalQuality: { uint16_t snr=0; - if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE) - eDebug("FE_READ_SNR failed (%m)"); + if (!m_simulate) + { + if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE) + eDebug("FE_READ_SNR failed (%m)"); + } return snr; } case signalQualitydB: /* this will move into the driver */ { uint16_t snr=0; + if (m_simulate) + return 0; if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE) eDebug("FE_READ_SNR failed (%m)"); if (!strcmp(m_description, "BCM4501 (internal)")) @@ -692,13 +737,13 @@ int eDVBFrontend::readFrontendData(int type) 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); - + if (fval1 < 10.0) { fval2 = SNR_COEFF[0]; @@ -710,7 +755,7 @@ int eDVBFrontend::readFrontendData(int type) fval1 = fval2; } snr_in_db = fval1; - + return (int)(snr_in_db * 100.0); } else if (strstr(m_description, "Alps BSBE1 C01A") || @@ -774,8 +819,11 @@ int eDVBFrontend::readFrontendData(int type) case signalPower: { uint16_t strength=0; - if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE) - eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)"); + if (!m_simulate) + { + if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE) + eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)"); + } return strength; } case locked: @@ -785,9 +833,13 @@ int eDVBFrontend::readFrontendData(int type) #else fe_status_t status; #endif - if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE ) - eDebug("FE_READ_STATUS failed (%m)"); - return !!(status&FE_HAS_LOCK); + if (!m_simulate) + { + if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE ) + eDebug("FE_READ_STATUS failed (%m)"); + return !!(status&FE_HAS_LOCK); + } + return 1; } case synced: { @@ -796,9 +848,13 @@ int eDVBFrontend::readFrontendData(int type) #else fe_status_t status; #endif - if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE ) - eDebug("FE_READ_STATUS failed (%m)"); - return !!(status&FE_HAS_SYNC); + if (!m_simulate) + { + if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE ) + eDebug("FE_READ_STATUS failed (%m)"); + return !!(status&FE_HAS_SYNC); + } + return 1; } case frontendNumber: return m_slotid; @@ -1211,7 +1267,7 @@ void eDVBFrontend::getFrontendStatus(ePyObject dest) void eDVBFrontend::getTransponderData(ePyObject dest, bool original) { - if (m_fd != -1 && dest && PyDict_Check(dest)) + if (dest && PyDict_Check(dest)) { switch(m_type) { @@ -1220,8 +1276,11 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original) case feTerrestrial: { FRONTENDPARAMETERS front; - if (!original && ioctl(m_fd, FE_GET_FRONTEND, &front)<0) - eDebug("FE_GET_FRONTEND (%m)"); + if (!original) + { + if (!m_simulate && m_fd != -1 && ioctl(m_fd, FE_GET_FRONTEND, &front)<0) + eDebug("FE_GET_FRONTEND (%m)"); + } else { const FRONTENDPARAMETERS &parm = original ? this->parm : front; @@ -1290,6 +1349,8 @@ void eDVBFrontend::getFrontendData(ePyObject dest) #endif int eDVBFrontend::readInputpower() { + if (m_simulate) + 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); @@ -1325,7 +1386,7 @@ int eDVBFrontend::readInputpower() bool eDVBFrontend::setSecSequencePos(int steps) { - eDebug("set sequence pos %d", steps); + eDebugNoSimulate("set sequence pos %d", steps); if (!steps) return false; while( steps > 0 ) @@ -1372,12 +1433,12 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() ) { long *sec_fe_data = sec_fe->m_data; -// eDebug("tuneLoop %d\n", m_sec_sequence.current()->cmd); +// eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd); switch (m_sec_sequence.current()->cmd) { case eSecCommand::SLEEP: delay = m_sec_sequence.current()++->msec; - eDebug("[SEC] sleep %dms", delay); + eDebugNoSimulate("[SEC] sleep %dms", delay); break; case eSecCommand::GOTO: if ( !setSecSequencePos(m_sec_sequence.current()->steps) ) @@ -1386,7 +1447,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer case eSecCommand::SET_VOLTAGE: { int voltage = m_sec_sequence.current()++->voltage; - eDebug("[SEC] setVoltage %d", voltage); + eDebugNoSimulate("[SEC] setVoltage %d", voltage); sec_fe->setVoltage(voltage); break; } @@ -1423,40 +1484,41 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer break; } case eSecCommand::SET_TONE: - eDebug("[SEC] setTone %d", m_sec_sequence.current()->tone); + eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone); sec_fe->setTone(m_sec_sequence.current()++->tone); break; case eSecCommand::SEND_DISEQC: sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc); - eDebugNoNewLine("[SEC] sendDiseqc: "); + eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: "); for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i) - eDebugNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]); - eDebug(""); + eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]); + eDebugNoSimulate(""); ++m_sec_sequence.current(); break; case eSecCommand::SEND_TONEBURST: - eDebug("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst); + eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst); sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst); break; case eSecCommand::SET_FRONTEND: - eDebug("[SEC] setFrontend"); + eDebugNoSimulate("[SEC] setFrontend"); setFrontend(); ++m_sec_sequence.current(); break; case eSecCommand::START_TUNE_TIMEOUT: { - m_timeout->start(m_sec_sequence.current()->timeout, 1); + if (!m_simulate) + m_timeout->start(m_sec_sequence.current()->timeout, 1); ++m_sec_sequence.current(); break; } case eSecCommand::SET_TIMEOUT: m_timeoutCount = m_sec_sequence.current()++->val; - eDebug("[SEC] set timeout %d", m_timeoutCount); + eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount); break; case eSecCommand::IF_TIMEOUT_GOTO: if (!m_timeoutCount) { - eDebug("[SEC] rotor timout"); + eDebugNoSimulate("[SEC] rotor timout"); setSecSequencePos(m_sec_sequence.current()->steps); } else @@ -1468,23 +1530,23 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer if ( idx == 0 || idx == 1 ) { m_idleInputpower[idx] = sec_fe->readInputpower(); - eDebug("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]); + eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]); } else - eDebug("[SEC] idleInputpower measure index(%d) out of bound !!!", idx); + eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx); break; } case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO: { eSecCommand::pair &compare = m_sec_sequence.current()->compare; int idx = compare.val; - if ( idx == 0 || idx == 1 ) + if ( !m_simulate && (idx == 0 || idx == 1) ) { int idle = sec_fe->readInputpower(); int diff = abs(idle-m_idleInputpower[idx]); if ( diff > 0) { - eDebug("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff); + eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff); setSecSequencePos(compare.steps); break; } @@ -1494,23 +1556,28 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer } case eSecCommand::IF_TUNER_LOCKED_GOTO: { + eSecCommand::rotor &cmd = m_sec_sequence.current()->measure; + if (m_simulate) + { + setSecSequencePos(cmd.steps); + break; + } int signal = 0; int isLocked = readFrontendData(locked); m_idleInputpower[0] = m_idleInputpower[1] = 0; - eSecCommand::rotor &cmd = m_sec_sequence.current()->measure; if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 50) || !cmd.lastSignal)) { if (cmd.lastSignal) - eDebug("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal); + eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal); else { - eDebug("[SEC] locked step %d ok", cmd.okcount); + eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount); cmd.lastSignal = signal; } ++cmd.okcount; if (cmd.okcount > 4) { - eDebug("ok > 4 .. goto %d\n",cmd.steps); + eDebugNoSimulate("ok > 4 .. goto %d\n",cmd.steps); setSecSequencePos(cmd.steps); m_state = stateLock; m_stateChanged(this); @@ -1522,9 +1589,9 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer else { if (isLocked) - eDebug("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal); + eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal); else - eDebug("[SEC] rotor locked step %d failed (not locked)", cmd.okcount); + eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount); --m_timeoutCount; if (!m_timeoutCount && m_retryCount > 0) --m_retryCount; @@ -1536,23 +1603,30 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer } case eSecCommand::MEASURE_RUNNING_INPUTPOWER: m_runningInputpower = sec_fe->readInputpower(); - eDebug("[SEC] runningInputpower is %d", m_runningInputpower); + eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower); ++m_sec_sequence.current(); break; case eSecCommand::SET_ROTOR_MOVING: - m_sec->setRotorMoving(true); + if (!m_simulate) + m_sec->setRotorMoving(true); ++m_sec_sequence.current(); break; case eSecCommand::SET_ROTOR_STOPPED: - m_sec->setRotorMoving(false); + if (!m_simulate) + m_sec->setRotorMoving(false); ++m_sec_sequence.current(); break; case eSecCommand::IF_INPUTPOWER_DELTA_GOTO: { - int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1]; eSecCommand::rotor &cmd = m_sec_sequence.current()->measure; + if (m_simulate) + { + setSecSequencePos(cmd.steps); + break; + } + int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1]; const char *txt = cmd.direction ? "running" : "stopped"; - eDebug("[SEC] waiting for rotor %s %d, idle %d, delta %d", + eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d", txt, m_runningInputpower, idleInputpower, @@ -1561,17 +1635,17 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) ) { ++cmd.okcount; - eDebug("[SEC] rotor %s step %d ok", txt, cmd.okcount); + eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount); if ( cmd.okcount > 6 ) { - eDebug("[SEC] rotor is %s", txt); + eDebugNoSimulate("[SEC] rotor is %s", txt); if (setSecSequencePos(cmd.steps)) break; } } else { - eDebug("[SEC] rotor not %s... reset counter.. increase timeout", txt); + eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt); --m_timeoutCount; if (!m_timeoutCount && m_retryCount > 0) --m_retryCount; @@ -1587,7 +1661,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer ++m_sec_sequence.current(); break; case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS: - eDebug("[SEC] invalidate current switch params"); + eDebugNoSimulate("[SEC] invalidate current switch params"); sec_fe_data[CSW] = -1; sec_fe_data[UCSW] = -1; sec_fe_data[TONEBURST] = -1; @@ -1597,11 +1671,11 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer sec_fe_data[CSW] = sec_fe_data[NEW_CSW]; sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW]; sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST]; - eDebug("[SEC] update current switch params"); + eDebugNoSimulate("[SEC] update current switch params"); ++m_sec_sequence.current(); break; case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS: - eDebug("[SEC] invalidate current rotorparams"); + eDebugNoSimulate("[SEC] invalidate current rotorparams"); sec_fe_data[ROTOR_CMD] = -1; sec_fe_data[ROTOR_POS] = -1; ++m_sec_sequence.current(); @@ -1609,17 +1683,17 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer case eSecCommand::UPDATE_CURRENT_ROTORPARAMS: sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD]; sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS]; - eDebug("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]); + eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]); ++m_sec_sequence.current(); break; case eSecCommand::SET_ROTOR_DISEQC_RETRYS: m_retryCount = m_sec_sequence.current()++->val; - eDebug("[SEC] set rotor retries %d", m_retryCount); + eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount); break; case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO: if (!m_retryCount) { - eDebug("[SEC] no more rotor retrys"); + eDebugNoSimulate("[SEC] no more rotor retrys"); setSecSequencePos(m_sec_sequence.current()->steps); } else @@ -1627,72 +1701,81 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer break; case eSecCommand::SET_POWER_LIMITING_MODE: { - char proc_name[64]; - sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid); - FILE *f=fopen(proc_name, "w"); - if (f) // new interface exist? + if (!m_simulate) { - bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic; - if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0) - eDebug("write %s failed!! (%m)", proc_name); - else - eDebug("[SEC] set %s current limiting", slimiting ? "static" : "dynamic"); - fclose(f); - } - else if (sec_fe->m_need_rotor_workaround) - { - char dev[16]; - int slotid = sec_fe->m_slotid; - // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000 - if (slotid < 2) - sprintf(dev, "/dev/i2c/%d", slotid); - else if (slotid == 2) - sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2 - else if (slotid == 3) - sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4 - int fd = ::open(dev, O_RDWR); - - unsigned char data[2]; - ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1); - if(::read(fd, data, 1) != 1) - eDebug("[SEC] error read lnbp (%m)"); - if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic ) + char proc_name[64]; + sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid); + FILE *f=fopen(proc_name, "w"); + if (f) // new interface exist? { - data[0] |= 0x80; // enable static current limiting - eDebug("[SEC] set static current limiting"); + bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic; + if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0) + eDebugNoSimulate("write %s failed!! (%m)", proc_name); + else + eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic"); + fclose(f); } - else + else if (sec_fe->m_need_rotor_workaround) { - data[0] &= ~0x80; // enable dynamic current limiting - eDebug("[SEC] set dynamic current limiting"); + char dev[16]; + int slotid = sec_fe->m_slotid; + // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000 + if (slotid < 2) + sprintf(dev, "/dev/i2c/%d", slotid); + else if (slotid == 2) + sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2 + else if (slotid == 3) + sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4 + int fd = ::open(dev, O_RDWR); + + unsigned char data[2]; + ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1); + if(::read(fd, data, 1) != 1) + eDebugNoSimulate("[SEC] error read lnbp (%m)"); + if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic ) + { + data[0] |= 0x80; // enable static current limiting + eDebugNoSimulate("[SEC] set static current limiting"); + } + else + { + data[0] &= ~0x80; // enable dynamic current limiting + eDebugNoSimulate("[SEC] set dynamic current limiting"); + } + if(::write(fd, data, 1) != 1) + eDebugNoSimulate("[SEC] error write lnbp (%m)"); + ::close(fd); } - if(::write(fd, data, 1) != 1) - eDebug("[SEC] error write lnbp (%m)"); - ::close(fd); } ++m_sec_sequence.current(); break; } default: - eDebug("[SEC] unhandled sec command %d", + eDebugNoSimulate("[SEC] unhandled sec command %d", ++m_sec_sequence.current()->cmd); ++m_sec_sequence.current(); } - m_tuneTimer->start(delay,true); + if (!m_simulate) + m_tuneTimer->start(delay,true); } if (regFE) regFE->dec_use(); + if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end()) + tuneLoop(); } void eDVBFrontend::setFrontend() { - eDebug("setting frontend %d", m_dvbid); - m_sn->start(); - feEvent(-1); - if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) + if (!m_simulate) { - perror("FE_SET_FRONTEND failed"); - return; + eDebug("setting frontend %d", m_dvbid); + m_sn->start(); + feEvent(-1); + if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) + { + perror("FE_SET_FRONTEND failed"); + return; + } } } @@ -1715,7 +1798,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout); if (!res) { - eDebug("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d", + eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d", feparm.system, feparm.frequency, feparm.polarisation, @@ -1759,7 +1842,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, parm_u_qpsk_fec_inner = FEC_7_8; break; default: - eDebug("no valid fec for DVB-S set.. assume auto"); + eDebugNoSimulate("no valid fec for DVB-S set.. assume auto"); case eDVBFrontendParametersSatellite::FEC::fAuto: parm_u_qpsk_fec_inner = FEC_AUTO; break; @@ -1797,7 +1880,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10; break; default: - eDebug("no valid fec for DVB-S2 set.. abort !!"); + eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!"); return -EINVAL; } parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff @@ -1811,10 +1894,10 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, // FIXME !!! get frequency range from tuner if ( parm_frequency < 900000 || parm_frequency > 2200000 ) { - eDebug("%d mhz out of tuner range.. dont tune", parm_frequency/1000); + eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000); return -EINVAL; } - eDebug("tuning to %d mhz", parm_frequency/1000); + eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000); } return res; } @@ -1892,7 +1975,7 @@ RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm) parm_u_qam_fec_inner = FEC_AUTO; break; } - eDebug("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d", + eDebugNoSimulate("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, @@ -2051,13 +2134,13 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) { unsigned int timeout = 5000; - eDebug("(%d)tune", m_dvbid); + eDebugNoSimulate("(%d)tune", m_dvbid); m_timeout->stop(); int res=0; - if (!m_sn) + if (!m_sn && !m_simulate) { eDebug("no frontend device opened... do not try to tune !!!"); res = -ENODEV; @@ -2070,7 +2153,9 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) goto tune_error; } - m_sn->stop(); + if (!m_simulate) + m_sn->stop(); + m_sec_sequence.clear(); where.calcLockTimeout(timeout); @@ -2086,7 +2171,8 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) res = -EINVAL; goto tune_error; } - m_sec->setRotorMoving(false); + if (!m_simulate) + m_sec->setRotorMoving(false); res=prepare_sat(feparm, timeout); if (res) goto tune_error; @@ -2137,15 +2223,20 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) } } - m_tuneTimer->start(0,true); m_sec_sequence.current() = m_sec_sequence.begin(); - if (m_state != stateTuning) + if (!m_simulate) { - m_tuning = 1; - m_state = stateTuning; - m_stateChanged(this); + m_tuneTimer->start(0,true); + if (m_state != stateTuning) + { + m_tuning = 1; + m_state = stateTuning; + m_stateChanged(this); + } } + else + tuneLoop(); return res; @@ -2200,6 +2291,8 @@ RESULT eDVBFrontend::setVoltage(int voltage) default: return -ENODEV; } + if (m_simulate) + return 0; #if HAVE_DVB_API_VERSION < 3 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt); #else @@ -2236,6 +2329,8 @@ RESULT eDVBFrontend::setTone(int t) default: return -ENODEV; } + if (m_simulate) + return 0; #if HAVE_DVB_API_VERSION < 3 return ::ioctl(m_secfd, SEC_SET_TONE, tone); #else @@ -2249,6 +2344,8 @@ RESULT eDVBFrontend::setTone(int t) RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc) { + if (m_simulate) + return 0; #if HAVE_DVB_API_VERSION < 3 struct secCommand cmd; cmd.type = SEC_CMDTYPE_DISEQC_RAW; @@ -2273,6 +2370,8 @@ RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc) #endif RESULT eDVBFrontend::sendToneburst(int burst) { + if (m_simulate) + return 0; #if HAVE_DVB_API_VERSION < 3 secMiniCmd cmd = SEC_MINI_NONE; #else @@ -2369,7 +2468,7 @@ bool eDVBFrontend::setSlotInfo(ePyObject obj) !!strstr(m_description, "Alps -S") || !!strstr(m_description, "BCM4501"); m_can_handle_dvbs2 = IsDVBS2 == Py_True; - eDebug("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s", + eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s", m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" ); return true; arg_error: diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h index cbe3dfc2..0ab2387e 100644 --- a/lib/dvb/frontend.h +++ b/lib/dvb/frontend.h @@ -68,6 +68,7 @@ public: Signal1 m_stateChanged; private: DECLARE_REF(eDVBFrontend); + bool m_simulate; bool m_enabled; int m_type; int m_dvbid; @@ -106,7 +107,7 @@ private: bool setSecSequencePos(int steps); static int PriorityOrder; public: - eDVBFrontend(int adap, int fe, int &ok); + eDVBFrontend(int adap, int fe, int &ok, bool simulate=false); virtual ~eDVBFrontend(); int readInputpower(); @@ -141,6 +142,7 @@ public: int openFrontend(); int closeFrontend(bool force=false); const char *getDescription() const { return m_description; } + bool is_simulate() const { return m_simulate; } }; #endif // SWIG diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 5fb1e9ee..940d2e7d 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -524,9 +524,9 @@ void eDVBServicePMTHandler::SDTScanEvent(int event) } } -int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue) +int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *cue, bool simulate) { - RESULT res; + RESULT res=0; m_reference = ref; m_use_decode_demux = use_decode_demux; @@ -536,16 +536,17 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, { eDVBChannelID chid; ref.getChannelID(chid); - res = m_resourceManager->allocateChannel(chid, m_channel); - eDebug("allocate Channel: res %d", res); + res = m_resourceManager->allocateChannel(chid, m_channel, simulate); + if (!simulate) + eDebug("allocate Channel: res %d", res); ePtr db; if (!m_resourceManager->getChannelList(db)) - db->getService((eServiceReferenceDVB&)m_reference, m_service); + db->getService((eServiceReferenceDVB&)m_reference, m_service); - if (!res) + if (!res && !simulate) eDVBCIInterfaces::getInstance()->addPMTHandler(this); - } else + } else if (!simulate) // no simulation of playback services { eDVBMetaParser parser; @@ -577,37 +578,40 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, m_channel = m_pvr_channel; } - if (m_channel) + if (!simulate) { - m_channel->connectStateChange( - slot(*this, &eDVBServicePMTHandler::channelStateChanged), - m_channelStateChanged_connection); - m_last_channel_state = -1; - channelStateChanged(m_channel); - - m_channel->connectEvent( - slot(*this, &eDVBServicePMTHandler::channelEvent), - m_channelEvent_connection); + if (m_channel) + { + m_channel->connectStateChange( + slot(*this, &eDVBServicePMTHandler::channelStateChanged), + m_channelStateChanged_connection); + m_last_channel_state = -1; + channelStateChanged(m_channel); + + m_channel->connectEvent( + slot(*this, &eDVBServicePMTHandler::channelEvent), + m_channelEvent_connection); - if (ref.path.empty()) + if (ref.path.empty()) + { + delete m_dvb_scan; + m_dvb_scan = new eDVBScan(m_channel, true, false); + m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); + } + } else { - delete m_dvb_scan; - m_dvb_scan = new eDVBScan(m_channel, true, false); - m_dvb_scan->connectEvent(slot(*this, &eDVBServicePMTHandler::SDTScanEvent), m_scan_event_connection); + if (res == eDVBResourceManager::errAllSourcesBusy) + serviceEvent(eventNoResources); + else /* errChidNotFound, errNoChannelList, errChannelNotInList, errNoSourceFound */ + serviceEvent(eventMisconfiguration); + return res; } - } else - { - if (res == eDVBResourceManager::errAllSourcesBusy) - serviceEvent(eventNoResources); - else /* errChidNotFound, errNoChannelList, errChannelNotInList, errNoSourceFound */ - serviceEvent(eventMisconfiguration); - return res; - } - if (m_pvr_channel) - { - m_pvr_channel->setCueSheet(cue); - m_pvr_channel->playFile(ref.path.c_str()); + if (m_pvr_channel) + { + m_pvr_channel->setCueSheet(cue); + m_pvr_channel->playFile(ref.path.c_str()); + } } return res; @@ -642,6 +646,7 @@ void eDVBServicePMTHandler::free() m_pvr_channel->stopFile(); m_pvr_channel->setCueSheet(0); } + m_PMT.stop(); m_PAT.stop(); m_service = 0; diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index f34d761a..9b33d30b 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -202,7 +202,7 @@ public: int getChannel(eUsePtr &channel); void resetCachedProgram() { m_have_cached_program = false; } - int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0); + int tune(eServiceReferenceDVB &ref, int use_decode_demux, eCueSheet *sg=0, bool simulate=false); void free(); private: bool m_have_cached_program; diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index a409f43d..70cbf047 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -36,8 +36,8 @@ void eDVBSatelliteEquipmentControl::setParam(int param, int value) m_params[param]=value; } -eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList &avail_frontends) - :m_lnbidx(-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_rotorMoving(false) +eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrList &avail_frontends, eSmartPtrList &avail_simulate_frontends) + :m_lnbidx(-1), m_curSat(m_lnbs[0].m_satellites.end()), m_avail_frontends(avail_frontends), m_avail_simulate_frontends(avail_simulate_frontends), m_rotorMoving(false) { if (!instance) instance = this; @@ -114,13 +114,27 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl(eSmartPtrListis_simulate(); int score=0, satcount=0; if (highest_score_lnb) *highest_score_lnb = -1; + eSecDebugNoSimulate("canTune %d", slot_id); + for (int idx=0; idx <= m_lnbidx; ++idx ) { bool rotor=false; @@ -130,6 +144,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite int ret = 0; eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters; + eSecDebugNoSimulate("lnb %d found", idx); + satcount += lnb_param.m_satellites.size(); std::map::iterator sit = @@ -147,6 +163,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite toneburst = di_param.m_toneburst_param, curRotorPos; + eSecDebugNoSimulate("sat %d found", sat.orbital_position); fe->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr); @@ -175,11 +192,14 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite ret = 15000; } + eSecDebugNoSimulate("ret1 %d", ret); + if (direct_connected) // frontend with direct connection? { long ocsw = -1, oucsw = -1, oToneburst = -1; + eSecDebugNoSimulate("direct"); fe->getData(eDVBFrontend::ROTOR_POS, curRotorPos); fe->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); fe->getData(eDVBFrontend::CSW, ocsw); @@ -199,6 +219,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite } linked_fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, (long&)linked_prev_ptr); } + eSecDebugNoSimulate("ret2 %d", ret); while (ret && linked_next_ptr != -1) // check for linked tuners.. { eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*) linked_next_ptr; @@ -213,6 +234,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite } linked_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, (long&)linked_next_ptr); } + eSecDebugNoSimulate("ret3 %d", ret); } else // linked frontend.. { @@ -232,6 +254,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite sec_fe->getData(eDVBFrontend::CSW, ocsw); sec_fe->getData(eDVBFrontend::UCSW, oucsw); sec_fe->getData(eDVBFrontend::TONEBURST, oToneburst); + eSecDebug("(%ld != %ld) || \n(%d && (%ld != %ld || %ld != %ld) ) ||\n( %d && %ld != %d ) )", + csw, ocsw, diseqc, ucsw, oucsw, toneburst, oToneburst, rotor, curRotorPos, sat.orbital_position); if ( (csw != ocsw) || ( diseqc && (ucsw != oucsw || toneburst != oToneburst) ) || ( rotor && curRotorPos != sat.orbital_position ) ) @@ -241,15 +265,19 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite } } } + eSecDebugNoSimulate("ret4 %d", ret); } if (ret && rotor && curRotorPos != -1 && direct_connected) { ret -= abs(curRotorPos-sat.orbital_position); } + eSecDebugNoSimulate("ret5 %d", ret); + if (ret) if (satpos_depends_ptr != -1) { + eSecDebugNoSimulate("satpos depends"); eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr; if ( satpos_depends_to_fe->m_inuse ) { @@ -258,6 +286,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite if (!rotor || curRotorPos != sat.orbital_position) ret=0; } + eSecDebugNoSimulate("ret6 %d", ret); } if (ret) @@ -269,12 +298,14 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite ret=0; } + eSecDebugNoSimulate("ret %d, score old %d", ret, score); if (ret > score) { score = ret; if (highest_score_lnb) *highest_score_lnb = idx; } + eSecDebugNoSimulate("score new %d", score); } } } @@ -282,6 +313,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite score -= (satcount-1); if (score && m_not_linked_slot_mask & slot_id) score += 5; // increase score for tuners with direct sat connection + eSecDebugNoSimulate("final score %d", score); return score; } @@ -311,8 +343,20 @@ bool need_turn_fast(int turn_speed) #define VOLTAGE(x) (lnb_param.m_increased_voltage ? iDVBFrontend::voltage##x##_5 : iDVBFrontend::voltage##x) +#define eDebugNoSimulate(x...) \ + do { \ + if (!simulate) \ + eDebug(x); \ + } while(0) +// else \ +// { \ +// eDebugNoNewLine("SIMULATE:"); \ +// eDebug(x); \ +// } \ + RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int slot_id, unsigned int tunetimeout) { + bool simulate = ((eDVBFrontend*)&frontend)->is_simulate(); int lnb_idx = -1; if (canTune(sat, &frontend, slot_id, &lnb_idx)) { @@ -449,7 +493,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA && di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO && (lastcsw & 0xF0) && ((csw / 4) == (lastcsw / 4)) ) - eDebug("dont send committed cmd (fast diseqc)"); + eDebugNoSimulate("dont send committed cmd (fast diseqc)"); else { send_mask |= 1; @@ -480,7 +524,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA RotorCmd=sw_param.m_rotorPosNum; else // we must calc gotoxx cmd { - eDebug("Entry for %d,%d? not in Rotor Table found... i try gotoXX?", sat.orbital_position / 10, sat.orbital_position % 10 ); + eDebugNoSimulate("Entry for %d,%d? not in Rotor Table found... i try gotoXX?", sat.orbital_position / 10, sat.orbital_position % 10 ); useGotoXX = true; double SatLon = abs(sat.orbital_position)/10.00, @@ -493,10 +537,10 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA if ( rotor_param.m_gotoxx_parameters.m_lo_direction == eDVBSatelliteRotorParameters::WEST ) SiteLon = 360 - SiteLon; - eDebug("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon ); + eDebugNoSimulate("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon ); double satHourAngle = calcSatHourangle( SatLon, SiteLat, SiteLon ); - eDebug("PolarmountHourAngle=%lf", satHourAngle ); + eDebugNoSimulate("PolarmountHourAngle=%lf", satHourAngle ); static int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; @@ -526,7 +570,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA RotorCmd |= 0xE000; } } - eDebug("RotorCmd = %04x", RotorCmd); + eDebugNoSimulate("RotorCmd = %04x", RotorCmd); } } @@ -649,7 +693,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA sendDiSEqC = true; } - eDebug("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd); + eDebugNoSimulate("RotorCmd %02x, lastRotorCmd %02lx", RotorCmd, lastRotorCmd); if ( RotorCmd != -1 && RotorCmd != lastRotorCmd ) { eSecCommand::pair compare; @@ -854,7 +898,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA return 0; } } - eDebug("found no useable satellite configuration for %s freq %d%s %s on orbital position (%d)", + eDebugNoSimulate("found no useable satellite configuration for %s freq %d%s %s on orbital position (%d)", sat.system ? "DVB-S2" : "DVB-S", sat.frequency, sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal ? "H" : @@ -901,6 +945,15 @@ RESULT eDVBSatelliteEquipmentControl::clear() it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1); } + for (eSmartPtrList::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it) + { + it->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, -1); + it->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, -1); + it->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, -1); + it->m_frontend->setData(eDVBFrontend::ROTOR_POS, -1); + it->m_frontend->setData(eDVBFrontend::ROTOR_CMD, -1); + } + return 0; } @@ -1242,6 +1295,20 @@ RESULT eDVBSatelliteEquipmentControl::setTunerLinked(int tu1, int tu2) fclose(f); } } + } + + p1=p2=NULL; + for (eSmartPtrList::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it) + { + if (it->m_frontend->getSlotID() == tu1) + p1 = *it; + else if (it->m_frontend->getSlotID() == tu2) + p2 = *it; + } + if (p1 && p2) + { + p1->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)p2); + p2->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)p1); return 0; } } @@ -1264,11 +1331,26 @@ RESULT eDVBSatelliteEquipmentControl::setTunerDepends(int tu1, int tu2) p2 = *it; } if (p1 && p2) + { + p1->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p2); + p2->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p1); + } + + p1=p2=NULL; + for (eSmartPtrList::iterator it(m_avail_simulate_frontends.begin()); it != m_avail_simulate_frontends.end(); ++it) + { + if (it->m_frontend->getSlotID() == tu1) + p1 = *it; + else if (it->m_frontend->getSlotID() == tu2) + p2 = *it; + } + if (p1 && p2) { p1->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p2); p2->m_frontend->setData(eDVBFrontend::SATPOS_DEPENDS_PTR, (long)p1); return 0; } + return -1; } diff --git a/lib/dvb/sec.h b/lib/dvb/sec.h index e630df91..24c606f0 100644 --- a/lib/dvb/sec.h +++ b/lib/dvb/sec.h @@ -274,7 +274,7 @@ private: eDVBSatelliteLNBParameters m_lnbs[144]; // i think its enough int m_lnbidx; // current index for set parameters std::map::iterator m_curSat; - eSmartPtrList &m_avail_frontends; + eSmartPtrList &m_avail_frontends, &m_avail_simulate_frontends; bool m_rotorMoving; int m_not_linked_slot_mask; bool m_canMeasureInputPower; @@ -286,7 +286,7 @@ private: static int m_params[MAX_PARAMS]; public: #ifndef SWIG - eDVBSatelliteEquipmentControl(eSmartPtrList &avail_frontends); + eDVBSatelliteEquipmentControl(eSmartPtrList &avail_frontends, eSmartPtrList &avail_simulate_frontends); RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int frontend_id, unsigned int tunetimeout); int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *, int frontend_id, int *highest_score_lnb=0); bool currentLNBValid() { return m_lnbidx > -1 && m_lnbidx < (int)(sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters)); } diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 85c18794..9a3739a0 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -525,9 +525,9 @@ void eDVBCIInterfaces::removePMTHandler(eDVBServicePMTHandler *pmthandler) // eDebug("use_count is now %d", slot->use_count); slot = next; } + // check if another service is waiting for the CI + recheckPMTHandlers(); } - // check if another service is waiting for the CI - recheckPMTHandlers(); } void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler) diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 929aaa93..0385b9c2 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -848,7 +848,7 @@ public: virtual SWIG_VOID(RESULT) getError(int &SWIG_OUTPUT)=0; virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0; virtual RESULT prepareStreaming()=0; - virtual RESULT start()=0; + virtual RESULT start(bool simulate=false)=0; virtual RESULT stop()=0; virtual SWIG_VOID(RESULT) frontendInfo(ePtr &SWIG_OUTPUT)=0; virtual SWIG_VOID(RESULT) stream(ePtr &SWIG_OUTPUT)=0; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index e7d15ba7..c259a811 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2994,6 +2994,8 @@ void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event) case iTSMPEGDecoder::videoEvent::eventProgressiveChanged: m_event((iPlayableService*)this, evVideoProgressiveChanged); break; + default: + break; } } diff --git a/lib/service/servicedvbrecord.cpp b/lib/service/servicedvbrecord.cpp index 86461d05..89d022cc 100644 --- a/lib/service/servicedvbrecord.cpp +++ b/lib/service/servicedvbrecord.cpp @@ -14,6 +14,7 @@ eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref m_target_fd = -1; m_error = 0; m_streaming = 0; + m_simulate = false; } void eDVBServiceRecord::serviceEvent(int event) @@ -122,18 +123,19 @@ RESULT eDVBServiceRecord::prepareStreaming() return -1; } -RESULT eDVBServiceRecord::start() +RESULT eDVBServiceRecord::start(bool simulate) { + m_simulate = simulate; m_want_record = 1; /* when tune wasn't yet successfully, doRecord stays in "prepared"-state which is fine. */ m_event((iRecordableService*)this, evStart); return doRecord(); } - RESULT eDVBServiceRecord::stop() { - eDebug("stop recording!"); + if (!m_simulate) + eDebug("stop recording!"); if (m_state == stateRecording) { if (m_record) @@ -144,7 +146,7 @@ RESULT eDVBServiceRecord::stop() m_target_fd = -1; } m_state = statePrepared; - } else + } else if (!m_simulate) eDebug("(was not recording)"); if (m_state == statePrepared) { @@ -155,7 +157,6 @@ RESULT eDVBServiceRecord::stop() return 0; } - int eDVBServiceRecord::doPrepare() { /* allocate a ts recorder if we don't already have one. */ @@ -163,7 +164,7 @@ int eDVBServiceRecord::doPrepare() { m_pids_active.clear(); m_state = statePrepared; - return m_service_handler.tune(m_ref, 0); + return m_service_handler.tune(m_ref, 0, 0, m_simulate); } return 0; } @@ -181,7 +182,7 @@ int eDVBServiceRecord::doRecord() if (!m_tuned) return 0; /* try it again when we are tuned in */ - if (!m_record && m_tuned && !m_streaming) + if (!m_record && m_tuned && !m_streaming && !m_simulate) { eDebug("Recording to %s...", m_filename.c_str()); ::remove(m_filename.c_str()); diff --git a/lib/service/servicedvbrecord.h b/lib/service/servicedvbrecord.h index b46a73ea..17de033e 100644 --- a/lib/service/servicedvbrecord.h +++ b/lib/service/servicedvbrecord.h @@ -20,7 +20,7 @@ public: RESULT connectEvent(const Slot2 &event, ePtr &connection); RESULT prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id); RESULT prepareStreaming(); - RESULT start(); + RESULT start(bool simulate=false); RESULT stop(); RESULT stream(ePtr &ptr); RESULT getError(int &error) { error = m_error; return 0; } @@ -31,6 +31,7 @@ public: private: enum { stateIdle, statePrepared, stateRecording }; + bool m_simulate; int m_state, m_want_record; friend class eServiceFactoryDVB; eDVBServiceRecord(const eServiceReferenceDVB &ref); diff --git a/timer.py b/timer.py index be629099..750a8c03 100644 --- a/timer.py +++ b/timer.py @@ -3,6 +3,8 @@ from time import strftime, time, localtime, mktime from enigma import eTimer import datetime +import NavigationInstance + class TimerEntry: StateWaiting = 0 StatePrepared = 1 @@ -175,6 +177,27 @@ class Timer: insort(self.timer_list, entry) if not noRecalc: self.calcNextActivation() + +# small piece of example code to understand how to use record simulation +# if NavigationInstance.instance: +# lst = [ ] +# cnt = 0 +# for timer in self.timer_list: +# print "timer", cnt +# cnt += 1 +# if timer.state == 0: #waiting +# lst.append(NavigationInstance.instance.recordService(timer.service_ref)) +# else: +# print "STATE: ", timer.state +# +# for rec in lst: +# if rec.start(True): #simulate +# print "FAILED!!!!!!!!!!!!" +# else: +# print "OK!!!!!!!!!!!!!!" +# NavigationInstance.instance.stopRecordService(rec) +# else: +# print "no NAV" def setNextActivation(self, when): delay = int((when - time()) * 1000) -- 2.30.2