From 7ea97a85b8a5bc5a6f1fb75cb2c6335644b4ebc0 Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Tue, 17 May 2005 17:33:14 +0000 Subject: [PATCH] non blocking diseqc and sec stuff --- lib/dvb/frontend.cpp | 178 ++++++++++++++++++++++++------------------- lib/dvb/frontend.h | 12 ++- lib/dvb/idvb.h | 3 + lib/dvb/sec.cpp | 75 +++++++++++------- lib/dvb/sec.h | 71 +++++++++++++++++ 5 files changed, 233 insertions(+), 106 deletions(-) diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 9ec9a9e3..cdbf8a58 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -277,10 +277,13 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): m_type(-1) 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); + return; } @@ -358,6 +361,59 @@ void eDVBFrontend::timeout() m_tuning = 0; } +void eDVBFrontend::tuneLoop() // called by m_tuneTimer +{ + int delay=0; + if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() ) + { + switch (m_sec_sequence.current()->cmd) + { + case eSecCommand::SLEEP: + delay = m_sec_sequence.current()->msec; + break; + case eSecCommand::SET_VOLTAGE: + setVoltage(m_sec_sequence.current()->voltage); + break; + case eSecCommand::SET_TONE: + setTone(m_sec_sequence.current()->tone); + break; + case eSecCommand::SEND_DISEQC: + sendDiseqc(m_sec_sequence.current()->diseqc); + break; + case eSecCommand::SEND_TONEBURST: + sendToneburst(m_sec_sequence.current()->toneburst); + break; + case eSecCommand::SET_FRONTEND: + setFrontend(); + break; + case eSecCommand::IF_LOCK_GOTO: + case eSecCommand::IF_NOT_LOCK_GOTO: + default: + eDebug("unhandled sec command"); + } + m_sec_sequence.current()++; + m_tuneTimer->start(delay,true); + } +} + +void eDVBFrontend::setFrontend() +{ + eDebug("setting frontend..\n"); + if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) + { + perror("FE_SET_FRONTEND failed"); + return; + } + + if (m_state != stateTuning) + { + m_tuning = 1; + m_state = stateTuning; + m_stateChanged(this); + } + m_timeout->start(5000, 1); // 5 sec timeout. TODO: symbolrate dependent +} + RESULT eDVBFrontend::getFrontendType(int &t) { if (m_type == -1) @@ -371,12 +427,12 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) if (m_type == -1) return -ENODEV; - FRONTENDPARAMETERS parm; - feEvent(-1); - + + m_sec_sequence.clear(); + eDebug("eDVBFrontend::tune. type: %d", m_type); - + switch (m_type) { case feSatellite: @@ -519,23 +575,10 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) break; } } - - eDebug("setting frontend..\n"); - - if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) - { - perror("FE_SET_FRONTEND failed"); - return errno; - } - - if (m_state != stateTuning) - { - m_tuning = 1; - m_state = stateTuning; - m_stateChanged(this); - } - - m_timeout->start(5000, 1); // 5 sec timeout. TODO: symbolrate dependent + + m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 0) ); + m_tuneTimer->start(0,true); + m_sec_sequence.current() = m_sec_sequence.begin(); return 0; } @@ -607,70 +650,45 @@ RESULT eDVBFrontend::setTone(int t) #endif } +#if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD) + #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *) +#endif + RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc) { #if HAVE_DVB_API_VERSION < 3 - secCmdSequence seq; - secCommand cmd; - - if ( diseqc.len > 3 ) - { - seq.numCommands=1; - cmd.type = SEC_CMDTYPE_DISEQC_RAW; - cmd.u.diseqc.cmdtype = diseqc.data[0]; - eDebug("cmdtype is %02x", diseqc.data[0]); - cmd.u.diseqc.addr = diseqc.data[1]; - eDebug("cmdaddr is %02x", diseqc.data[1]); - cmd.u.diseqc.cmd = diseqc.data[2]; - eDebug("cmd is %02x", diseqc.data[2]); - cmd.u.diseqc.numParams = diseqc.len-3; - eDebug("numparams %d", diseqc.len-3); - - memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3); - for (int i=0; i < diseqc.len-3; ++i ) - eDebugNoNewLine("%02x ", diseqc.data[3+i]); - eDebug(""); - } - else - seq.numCommands=0; - - seq.continuousTone = diseqc.tone == toneOn ? SEC_TONE_ON : SEC_TONE_OFF; - switch ( diseqc.voltage ) - { - case voltageOff: - seq.voltage = SEC_VOLTAGE_OFF; - break; - case voltage13: - seq.voltage = SEC_VOLTAGE_13; - break; - case voltage18: - seq.voltage = SEC_VOLTAGE_18; - break; - } - seq.miniCommand = SEC_MINI_NONE; - seq.commands=&cmd; - - if ( ioctl(m_secfd, SEC_SEND_SEQUENCE, &seq) < 0 ) - { - eDebug("SEC_SEND_SEQUENCE failed ( %m )"); - return -EINVAL; - } - return 0; + struct secCommand cmd; + cmd.type = SEC_CMDTYPE_DISEQC_RAW; + cmd.u.diseqc.cmdtype = diseqc.data[0]; + cmd.u.diseqc.addr = diseqc.data[1]; + cmd.u.diseqc.cmd = diseqc.data[2]; + cmd.u.diseqc.numParams = diseqc.len-3; + memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3); + if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd)) #else - if ( !diseqc.len ) - return 0; struct dvb_diseqc_master_cmd cmd; - if (::ioctl(m_fd, FE_SET_TONE, SEC_TONE_OFF)) - return -EINVAL; - usleep(15 * 1000); memcpy(cmd.msg, diseqc.data, diseqc.len); cmd.msg_len = diseqc.len; - if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd)) +#endif + return -EINVAL; + return 0; +} + +#if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST) + #define SEC_DISEQC_SEND_BURST _IO('o', 96) +#endif +RESULT eDVBFrontend::sendToneburst(int burst) +{ +#if HAVE_DVB_API_VERSION < 3 + secMiniCmd cmd = SEC_MINI_NONE; + if ( burst == eDVBSatelliteDiseqcParameters::A ) + cmd = SEC_MINI_A; + else if ( burst == eDVBSatelliteDiseqcParameters::B ) + cmd = SEC_MINI_B; + if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd)) return -EINVAL; - usleep(15 * 1000); #endif - eDebug("diseqc ok"); return 0; } @@ -679,3 +697,9 @@ RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec) m_sec = sec; return 0; } + +RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list) +{ + m_sec_sequence = list; + return 0; +} diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h index f4e99fae..1a68f89e 100644 --- a/lib/dvb/frontend.h +++ b/lib/dvb/frontend.h @@ -3,6 +3,9 @@ #include #include +#include + +class eSecCommandList; class eDVBFrontendParameters: public iDVBFrontendParameters { @@ -39,15 +42,20 @@ class eDVBFrontend: public iDVBFrontend, public Object #if HAVE_DVB_API_VERSION < 3 int m_secfd; #endif + FRONTENDPARAMETERS parm; int m_state; Signal1 m_stateChanged; ePtr m_sec; eSocketNotifier *m_sn; int m_tuning; eTimer *m_timeout; - + eTimer *m_tuneTimer; + void feEvent(int); void timeout(); + eSecCommandList m_sec_sequence; + void tuneLoop(); // called by m_tuneTimer + void setFrontend(); public: eDVBFrontend(int adap, int fe, int &ok); virtual ~eDVBFrontend(); @@ -59,7 +67,9 @@ public: RESULT setTone(int tone); RESULT setVoltage(int voltage); RESULT sendDiseqc(const eDVBDiseqcCommand &diseqc); + RESULT sendToneburst(int burst); RESULT setSEC(iDVBSatelliteEquipmentControl *sec); + RESULT setSecSequence(const eSecCommandList &list); }; #endif diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index ef052d42..638aef91 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -361,6 +361,7 @@ public: }; class iDVBSatelliteEquipmentControl; +class eSecCommandList; class iDVBFrontend: public iObject { @@ -387,7 +388,9 @@ public: }; virtual RESULT setVoltage(int voltage)=0; virtual RESULT sendDiseqc(const eDVBDiseqcCommand &diseqc)=0; + virtual RESULT sendToneburst(int burst)=0; virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0; + virtual RESULT setSecSequence(const eSecCommandList &list)=0; }; class iDVBSatelliteEquipmentControl: public iObject diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index a90e1c0d..78e5949e 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -1,13 +1,11 @@ #include #include #if HAVE_DVB_API_VERSION < 3 -#include #define INVERSION Inversion #define FREQUENCY Frequency #define FEC_INNER FEC_inner #define SYMBOLRATE SymbolRate #else -#include #define INVERSION inversion #define FREQUENCY frequency #define FEC_INNER fec_inner @@ -25,7 +23,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl() eDVBSatelliteDiseqcParameters &diseqc_ref = astra1.m_diseqc_parameters; eDVBSatelliteSwitchParameters &switch_ref = astra1.m_switch_parameters; - lnb_ref.m_lof_hi = 10600000; + lnb_ref.m_lof_hi = 10607000; lnb_ref.m_lof_lo = 9750000; lnb_ref.m_lof_threshold = 11700000; @@ -96,37 +94,58 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && !hi ) ) tone = iDVBFrontend::toneOff; - eDVBDiseqcCommand diseqc; + eSecCommandList sec_sequence; -#if HAVE_DVB_API_VERSION < 3 - diseqc.voltage = voltage; - diseqc.tone = tone; -#else - frontend.setVoltage(voltage); -#endif - - if ( di_param.m_commited_cmd < eDVBSatelliteDiseqcParameters::NO ) + if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 ) { - diseqc.len = 4; - diseqc.data[0] = 0xe0; - diseqc.data[1] = 0x10; - diseqc.data[2] = 0x38; - diseqc.data[3] = di_param.m_commited_cmd; - - if (hi) - diseqc.data[3] |= 1; - - if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal) - diseqc.data[3] |= 2; + eDebug("rotor..."); + } + else if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0) + { + if ( di_param.m_commited_cmd < eDVBSatelliteDiseqcParameters::SENDNO || + di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO ) + { + sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) ); + } + + if ( di_param.m_commited_cmd < eDVBSatelliteDiseqcParameters::SENDNO ) + { + eDVBDiseqcCommand diseqc; + diseqc.len = 4; + diseqc.data[0] = 0xe0; + diseqc.data[1] = 0x10; + diseqc.data[2] = 0x38; + diseqc.data[3] = 0xF0 | (di_param.m_commited_cmd << 2); + + if (hi) + diseqc.data[3] |= 1; + + if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal) + diseqc.data[3] |= 2; + + sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) ); + } + + if ( di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO ) + { + sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 30) ); + } } else - diseqc.len = 0; + { + sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 10) ); + } - frontend.sendDiseqc(diseqc); + sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) ); + sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) ); + + frontend.setSecSequence(sec_sequence); -#if HAVE_DVB_API_VERSION > 2 - frontend.setTone(tone); -#endif return 0; } } diff --git a/lib/dvb/sec.h b/lib/dvb/sec.h index 6ce13492..6b205a9d 100644 --- a/lib/dvb/sec.h +++ b/lib/dvb/sec.h @@ -3,6 +3,77 @@ #include #include +#include + +class eSecCommand +{ +public: + enum { + NONE, SLEEP, SET_VOLTAGE, SET_TONE, SEND_DISEQC, SEND_TONEBURST, IF_LOCK_GOTO, IF_NOT_LOCK_GOTO, SET_FRONTEND + }; + int cmd; + union + { + int voltage; + int tone; + int toneburst; + int msec; + eDVBDiseqcCommand diseqc; + }; + eSecCommand( int cmd, int val ) + :cmd(cmd), voltage(val) + {} + eSecCommand( int cmd, eDVBDiseqcCommand diseqc ) + :cmd(cmd), diseqc(diseqc) + {} + eSecCommand() + :cmd(NONE) + {} +}; + +class eSecCommandList +{ + std::list secSequence; + std::list::iterator cur; +public: + eSecCommandList() + :cur(secSequence.end()) + { + } + void push_front(const eSecCommand &cmd) + { + secSequence.push_front(cmd); + } + void push_back(const eSecCommand &cmd) + { + secSequence.push_back(cmd); + } + void clear() + { + secSequence.clear(); + cur=secSequence.end(); + } + inline std::list::iterator ¤t() + { + return cur; + } + inline std::list::iterator begin() + { + return secSequence.begin(); + } + inline std::list::iterator end() + { + return secSequence.end(); + } + int size() const + { + return secSequence.size(); + } + operator bool() const + { + return secSequence.size(); + } +}; class eDVBSatelliteDiseqcParameters { -- 2.30.2