X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/bce53d4a67d1655a496eebe5912c8573e880114e..97d46aee1158e549c110d66a0e1c4185c3cbbdf3:/lib/dvb/frontend.cpp diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index f2fc12b3..f85a37fe 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -49,9 +49,7 @@ #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information -#ifdef FEC_9_10 - #warning "FEC_9_10 already exist in dvb api ... it seems it is now ready for DVB-S2" -#else +#if HAVE_DVB_API_VERSION < 5 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1) #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1) #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1) @@ -70,6 +68,16 @@ #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1) #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1) #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1) +#else + #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2) + #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3) + #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4) + #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6) + #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8) + #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9) + #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5) + #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5) + #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10) #endif #endif @@ -379,7 +387,7 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto) diff = 1 << 30; else - diff = abs(terrestrial.frequency - oterrestrial.frequency); + diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000; return 0; default: return -1; @@ -403,7 +411,7 @@ RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const return 0; case iDVBFrontend::feTerrestrial: hash = 0xEEEE0000; - hash |= (terrestrial.frequency/1000)&0xFFFF; + hash |= (terrestrial.frequency/1000000)&0xFFFF; return 0; default: return -1; @@ -447,8 +455,8 @@ int eDVBFrontend::PriorityOrder=0; 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_timeout(0), m_tuneTimer(0) + ,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) #endif @@ -477,7 +485,7 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate) int eDVBFrontend::openFrontend() { - if (m_sn) + if (m_state != stateClosed) return -1; // already opened m_state=stateIdle; @@ -596,7 +604,7 @@ int eDVBFrontend::closeFrontend(bool force) 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 @@ -652,32 +660,40 @@ void eDVBFrontend::feEvent(int w) if (res && (errno == EAGAIN)) break; - if (res) - { - eWarning("FE_GET_EVENT failed! %m"); - return; - } - if (w < 0) continue; #if HAVE_DVB_API_VERSION < 3 if (event.type == FE_COMPLETION_EV) #else - eDebug("(%d)fe event: status %x, inversion %s", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off"); + eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning); if (event.status & FE_HAS_LOCK) #endif { state = stateLock; } else { - if (m_tuning) + if (m_tuning) { state = stateTuning; +#if HAVE_DVB_API_VERSION >= 3 + if (event.status & FE_TIMEDOUT) { + eDebug("FE_TIMEDOUT! ..abort"); + m_tuneTimer->stop(); + timeout(); + return; + } + ++m_tuning; +#else + m_tuneTimer->stop(); + timeout(); +#endif + } 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) @@ -735,7 +751,7 @@ int eDVBFrontend::readFrontendData(int type) float SDS_SNRE = snr << 16; float snr_in_db; - if (parm_u_qpsk_fec_inner <= FEC_AUTO) // DVB-S1 / QPSK + if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK { static float SNR_COEFF[6] = { 100.0 / 4194304.0, @@ -789,7 +805,7 @@ int eDVBFrontend::readFrontendData(int type) ret = (int)(snr_in_db * 100); } else if (strstr(m_description, "Alps BSBE1 C01A") || - !strcmp(m_description, "Alps -S(STV0288)")) + strstr(m_description, "Alps -S(STV0288)")) { if (snr == 0) ret = 0; @@ -858,7 +874,7 @@ int eDVBFrontend::readFrontendData(int type) if (snr != 0) ret = 10 * (int)(-100 * (log10(snr) - log10(255))); } - else if (!strcmp(m_description, "BCM4506")) + else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505")) ret = (snr * 100) >> 8; if (type == signalQuality) @@ -963,7 +979,113 @@ void PutToDict(ePyObject &dict, const char*key, const char *value) eDebug("could not create PyObject for %s", key); } -void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization) +void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm) +{ + PutToDict(dict, "tuner_type", "DVB-S"); + PutToDict(dict, "frequency", feparm.frequency); + PutToDict(dict, "symbol_rate", feparm.symbol_rate); + PutToDict(dict, "orbital_position", feparm.orbital_position); + PutToDict(dict, "inversion", feparm.inversion); + PutToDict(dict, "fec_inner", feparm.fec); + PutToDict(dict, "modulation", feparm.modulation); + PutToDict(dict, "polarization", feparm.polarisation); + if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2) + { + PutToDict(dict, "rolloff", feparm.rolloff); + PutToDict(dict, "pilot", feparm.pilot); + } + PutToDict(dict, "system", feparm.system); +} + +void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm) +{ + PutToDict(dict, "tuner_type", "DVB-T"); + PutToDict(dict, "frequency", feparm.frequency); + PutToDict(dict, "bandwidth", feparm.bandwidth); + PutToDict(dict, "code_rate_lp", feparm.code_rate_LP); + PutToDict(dict, "code_rate_hp", feparm.code_rate_HP); + PutToDict(dict, "constellation", feparm.modulation); + PutToDict(dict, "transmission_mode", feparm.transmission_mode); + PutToDict(dict, "guard_interval", feparm.guard_interval); + PutToDict(dict, "hierarchy_information", feparm.hierarchy); + PutToDict(dict, "inversion", feparm.inversion); +} + +void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm) +{ + PutToDict(dict, "tuner_type", "DVB-C"); + PutToDict(dict, "frequency", feparm.frequency); + PutToDict(dict, "symbol_rate", feparm.symbol_rate); + PutToDict(dict, "modulation", feparm.modulation); + PutToDict(dict, "inversion", feparm.inversion); + PutToDict(dict, "fec_inner", feparm.fec_inner); +} + +#if HAVE_DVB_API_VERSION >= 5 +static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization) +{ + long tmp=0; + int frequency = parm_frequency + freq_offset; + PutToDict(dict, "frequency", frequency); + PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate); + PutToDict(dict, "orbital_position", orb_pos); + PutToDict(dict, "polarization", polarization); + + switch(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; + case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break; + case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break; + case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break; + case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break; + case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break; + case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break; + case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break; + case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break; + case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break; + default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n"); + } + + switch (p[0].u.data) + { + default: eDebug("got unsupported system from frontend! report as DVBS!"); + case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break; + case SYS_DVBS2: + { + switch (p[2].u.data) + { + default: eDebug("got unsupported rolloff from frontend! report as 0_20!"); + case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break; + case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break; + case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break; + } + PutToDict(dict, "rolloff", tmp); + + switch (p[3].u.data) + { + case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break; + case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break; + case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break; + } + PutToDict(dict, "pilot", tmp); + + tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break; + } + } + PutToDict(dict, "system", tmp); + + switch (p[1].u.data) + { + default: eDebug("got unsupported modulation from frontend! report as QPSK!"); + case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break; + case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break; + } + PutToDict(dict, "modulation", tmp); +} + +#else +static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization) { long tmp=0; int frequency = parm_frequency + freq_offset; @@ -983,7 +1105,7 @@ void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, l default: case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break; #if HAVE_DVB_API_VERSION >=3 - case FEC_S2_8PSK_1_2: + case FEC_S2_8PSK_1_2: case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break; case FEC_S2_8PSK_2_3: case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break; @@ -1036,8 +1158,9 @@ void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, l #endif PutToDict(dict, "system", tmp); } +#endif -void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm) +static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm) { long tmp=0; #if HAVE_DVB_API_VERSION < 3 @@ -1074,7 +1197,7 @@ void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm) PutToDict(dict, "modulation", tmp); } -void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm) +static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm) { long tmp=0; PutToDict(dict, "frequency", parm_frequency); @@ -1195,51 +1318,78 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original) { if (dest && PyDict_Check(dest)) { - switch(m_type) + FRONTENDPARAMETERS front; +#if HAVE_DVB_API_VERSION >= 5 + struct dtv_property p[4]; + struct dtv_properties cmdseq; + cmdseq.props = p; + cmdseq.num = 4; + p[0].cmd = DTV_DELIVERY_SYSTEM; + p[1].cmd = DTV_MODULATION; + p[2].cmd = DTV_ROLLOFF; + p[3].cmd = DTV_PILOT; +#endif + if (m_simulate || m_fd == -1 || original) + original = true; +#if HAVE_DVB_API_VERSION >= 5 + else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only + ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0) { - case feSatellite: - case feCable: - case feTerrestrial: + eDebug("FE_GET_PROPERTY failed (%m)"); + original = true; + } +#endif + else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0) + { + eDebug("FE_GET_FRONTEND failed (%m)"); + original = true; + } + if (original) + { + switch(m_type) { - FRONTENDPARAMETERS front; - if (m_fd == -1 && !original) - original = true; - else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0) - { - eDebug("FE_GET_FRONTEND failed (%m)"); - original = true; - } - { - const FRONTENDPARAMETERS &parm = original || m_simulate ? this->parm : front; - long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; - switch(parm_inversion & 3) - { - case INVERSION_ON: - tmp = eDVBFrontendParametersSatellite::Inversion_On; - break; - case INVERSION_OFF: - tmp = eDVBFrontendParametersSatellite::Inversion_Off; - default: - break; - } - PutToDict(dest, "inversion", tmp); - - switch(m_type) - { - case feSatellite: - fillDictWithSatelliteData(dest, original?parm:front, m_data[FREQ_OFFSET], m_cur_orbpos, m_cur_pol); - break; - case feCable: - fillDictWithCableData(dest, original?parm:front); - break; - case feTerrestrial: - fillDictWithTerrestrialData(dest, original?parm:front); - break; - } - } + case feSatellite: + PutSatelliteDataToDict(dest, oparm.sat); + break; + case feCable: + PutCableDataToDict(dest, oparm.cab); + break; + case feTerrestrial: + PutTerrestrialDataToDict(dest, oparm.ter); + break; + } + } + else + { + FRONTENDPARAMETERS &parm = front; + long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; + switch(parm_inversion & 3) + { + case INVERSION_ON: + tmp = eDVBFrontendParametersSatellite::Inversion_On; + break; + case INVERSION_OFF: + tmp = eDVBFrontendParametersSatellite::Inversion_Off; + default: + break; + } + PutToDict(dest, "inversion", tmp); + switch(m_type) + { + case feSatellite: +#if HAVE_DVB_API_VERSION >= 5 + fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation); +#else + fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation); +#endif + break; + case feCable: + fillDictWithCableData(dest, parm); + break; + case feTerrestrial: + fillDictWithTerrestrialData(dest, parm); + break; } - default: - break; } } } @@ -1349,7 +1499,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer state = sec_fe->m_state; } // sec_fe is closed... we must reopen it here.. - if (state == eDVBFrontend::stateClosed) + if (state == stateClosed) { regFE = prev; prev->inc_use(); @@ -1432,14 +1582,18 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst); break; case eSecCommand::SET_FRONTEND: - eDebugNoSimulate("[SEC] setFrontend"); - setFrontend(); - ++m_sec_sequence.current(); + { + int enableEvents = (m_sec_sequence.current()++)->val; + eDebugNoSimulate("[SEC] setFrontend %d", enableEvents); + setFrontend(enableEvents); break; + } case eSecCommand::START_TUNE_TIMEOUT: { + int tuneTimeout = m_sec_sequence.current()->timeout; + eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout); if (!m_simulate) - m_timeout->start(m_sec_sequence.current()->timeout, 1); + m_timeout->start(tuneTimeout, 1); ++m_sec_sequence.current(); break; } @@ -1497,23 +1651,27 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer int signal = 0; int isLocked = readFrontendData(locked); m_idleInputpower[0] = m_idleInputpower[1] = 0; - if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 50) || !cmd.lastSignal)) + --m_timeoutCount; + if (!m_timeoutCount && m_retryCount > 0) + --m_retryCount; + if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal)) { if (cmd.lastSignal) eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal); else { eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount); - cmd.lastSignal = signal; + if (!cmd.okcount) + cmd.lastSignal = signal; } ++cmd.okcount; if (cmd.okcount > 4) { - eDebugNoSimulate("ok > 4 .. goto %d\n",cmd.steps); + eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps); setSecSequencePos(cmd.steps); m_state = stateLock; m_stateChanged(this); - feEvent(-1); + feEvent(-1); // flush events m_sn->start(); break; } @@ -1524,9 +1682,6 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal); else eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount); - --m_timeoutCount; - if (!m_timeoutCount && m_retryCount > 0) - --m_retryCount; cmd.okcount=0; cmd.lastSignal=0; } @@ -1540,12 +1695,12 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer 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: @@ -1558,6 +1713,9 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer } int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1]; const char *txt = cmd.direction ? "running" : "stopped"; + --m_timeoutCount; + if (!m_timeoutCount && m_retryCount > 0) + --m_retryCount; eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d", txt, m_runningInputpower, @@ -1578,9 +1736,6 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer else { eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt); - --m_timeoutCount; - if (!m_timeoutCount && m_retryCount > 0) - --m_retryCount; cmd.okcount=0; } ++m_sec_sequence.current(); @@ -1696,17 +1851,80 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer tuneLoop(); } -void eDVBFrontend::setFrontend() +void eDVBFrontend::setFrontend(bool recvEvents) { if (!m_simulate) { eDebug("setting frontend %d", m_dvbid); - m_sn->start(); - feEvent(-1); - if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) + if (recvEvents) + m_sn->start(); + feEvent(-1); // flush events +#if HAVE_DVB_API_VERSION >= 5 + if (m_type == iDVBFrontend::feSatellite) { - perror("FE_SET_FRONTEND failed"); - return; + fe_rolloff_t rolloff = ROLLOFF_35; + fe_pilot_t pilot = PILOT_OFF; + fe_modulation_t modulation = QPSK; + fe_delivery_system_t system = SYS_DVBS; + switch(oparm.sat.system) + { + case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break; + case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break; + }; + switch(oparm.sat.modulation) + { + case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break; + case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break; + case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break; + }; + switch(oparm.sat.pilot) + { + case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break; + case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break; + case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break; + }; + switch(oparm.sat.rolloff) + { + case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break; + case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break; + case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break; + }; + struct dtv_property p[10]; + struct dtv_properties cmdseq; + cmdseq.props = p; + p[0].cmd = DTV_CLEAR; + p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system; + p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency; + p[3].cmd = DTV_MODULATION, p[3].u.data = modulation; + p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate; + p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner; + p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion; + if (system == SYS_DVBS2) + { + p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff; + p[8].cmd = DTV_PILOT, p[8].u.data = pilot; + p[9].cmd = DTV_TUNE; + cmdseq.num = 10; + } + else + { + p[7].cmd = DTV_TUNE; + cmdseq.num = 8; + } + if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1) + { + perror("FE_SET_PROPERTY failed"); + return; + } + } + else +#endif + { + if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) + { + perror("FE_SET_FRONTEND failed"); + return; + } } } } @@ -1753,8 +1971,6 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, feparm.fec, feparm.orbital_position); #endif - m_cur_pol = feparm.polarisation; - m_cur_orbpos = feparm.orbital_position; parm_u_qpsk_symbol_rate = feparm.symbol_rate; switch (feparm.inversion) { @@ -1770,6 +1986,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, break; } if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S) + { switch (feparm.fec) { case eDVBFrontendParametersSatellite::FEC_None: @@ -1796,6 +2013,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, parm_u_qpsk_fec_inner = FEC_AUTO; break; } + } #if HAVE_DVB_API_VERSION >= 3 else // DVB_S2 { @@ -1832,12 +2050,15 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!"); return -EINVAL; } +#if HAVE_DVB_API_VERSION < 5 parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot - if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK) { + if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK) + { parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9); // 8PSK fec driver values are decimal 9 bigger } +#endif } #endif // FIXME !!! get frequency range from tuner @@ -1848,6 +2069,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, } eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000); } + oparm.sat = feparm; return res; } @@ -1930,6 +2152,7 @@ RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm) parm_u_qam_fec_inner, parm_u_qam_modulation, parm_inversion); + oparm.cab = feparm; return 0; } @@ -2077,6 +2300,7 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial parm_inversion = INVERSION_AUTO; break; } + oparm.ter = feparm; return 0; } @@ -2120,8 +2344,22 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) 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; @@ -2141,7 +2379,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) goto tune_error; m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) ); - m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) ); + m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) ); break; } case feTerrestrial: @@ -2166,7 +2404,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) ); else m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) ); - m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) ); + m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) ); break; } @@ -2177,9 +2415,9 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) if (!m_simulate) { m_tuneTimer->start(0,true); + m_tuning = 1; if (m_state != stateTuning) { - m_tuning = 1; m_state = stateTuning; m_stateChanged(this); }